12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- ExprCXX.h - Classes for representing expressions ---------*- 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
- //
- //===----------------------------------------------------------------------===//
- //
- /// \file
- /// Defines the clang::Expr interface and subclasses for C++ expressions.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_EXPRCXX_H
- #define LLVM_CLANG_AST_EXPRCXX_H
- #include "clang/AST/ASTConcept.h"
- #include "clang/AST/ComputeDependence.h"
- #include "clang/AST/Decl.h"
- #include "clang/AST/DeclBase.h"
- #include "clang/AST/DeclCXX.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/AST/DeclarationName.h"
- #include "clang/AST/DependenceFlags.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/NestedNameSpecifier.h"
- #include "clang/AST/OperationKinds.h"
- #include "clang/AST/Stmt.h"
- #include "clang/AST/StmtCXX.h"
- #include "clang/AST/TemplateBase.h"
- #include "clang/AST/Type.h"
- #include "clang/AST/UnresolvedSet.h"
- #include "clang/Basic/ExceptionSpecificationType.h"
- #include "clang/Basic/ExpressionTraits.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/Lambda.h"
- #include "clang/Basic/LangOptions.h"
- #include "clang/Basic/OperatorKinds.h"
- #include "clang/Basic/SourceLocation.h"
- #include "clang/Basic/Specifiers.h"
- #include "clang/Basic/TypeTraits.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/None.h"
- #include "llvm/ADT/Optional.h"
- #include "llvm/ADT/PointerUnion.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/iterator_range.h"
- #include "llvm/Support/Casting.h"
- #include "llvm/Support/Compiler.h"
- #include "llvm/Support/TrailingObjects.h"
- #include <cassert>
- #include <cstddef>
- #include <cstdint>
- #include <memory>
- namespace clang {
- class ASTContext;
- class DeclAccessPair;
- class IdentifierInfo;
- class LambdaCapture;
- class NonTypeTemplateParmDecl;
- class TemplateParameterList;
- //===--------------------------------------------------------------------===//
- // C++ Expressions.
- //===--------------------------------------------------------------------===//
- /// A call to an overloaded operator written using operator
- /// syntax.
- ///
- /// Represents a call to an overloaded operator written using operator
- /// syntax, e.g., "x + y" or "*p". While semantically equivalent to a
- /// normal call, this AST node provides better information about the
- /// syntactic representation of the call.
- ///
- /// In a C++ template, this expression node kind will be used whenever
- /// any of the arguments are type-dependent. In this case, the
- /// function itself will be a (possibly empty) set of functions and
- /// function templates that were found by name lookup at template
- /// definition time.
- class CXXOperatorCallExpr final : public CallExpr {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- SourceRange Range;
- // CXXOperatorCallExpr has some trailing objects belonging
- // to CallExpr. See CallExpr for the details.
- SourceRange getSourceRangeImpl() const LLVM_READONLY;
- CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn,
- ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
- ADLCallKind UsesADL);
- CXXOperatorCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
- public:
- static CXXOperatorCallExpr *
- Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn,
- ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
- SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
- ADLCallKind UsesADL = NotADL);
- static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
- unsigned NumArgs, bool HasFPFeatures,
- EmptyShell Empty);
- /// Returns the kind of overloaded operator that this expression refers to.
- OverloadedOperatorKind getOperator() const {
- return static_cast<OverloadedOperatorKind>(
- CXXOperatorCallExprBits.OperatorKind);
- }
- static bool isAssignmentOp(OverloadedOperatorKind Opc) {
- return Opc == OO_Equal || Opc == OO_StarEqual || Opc == OO_SlashEqual ||
- Opc == OO_PercentEqual || Opc == OO_PlusEqual ||
- Opc == OO_MinusEqual || Opc == OO_LessLessEqual ||
- Opc == OO_GreaterGreaterEqual || Opc == OO_AmpEqual ||
- Opc == OO_CaretEqual || Opc == OO_PipeEqual;
- }
- bool isAssignmentOp() const { return isAssignmentOp(getOperator()); }
- static bool isComparisonOp(OverloadedOperatorKind Opc) {
- switch (Opc) {
- case OO_EqualEqual:
- case OO_ExclaimEqual:
- case OO_Greater:
- case OO_GreaterEqual:
- case OO_Less:
- case OO_LessEqual:
- case OO_Spaceship:
- return true;
- default:
- return false;
- }
- }
- bool isComparisonOp() const { return isComparisonOp(getOperator()); }
- /// Is this written as an infix binary operator?
- bool isInfixBinaryOp() const;
- /// Returns the location of the operator symbol in the expression.
- ///
- /// When \c getOperator()==OO_Call, this is the location of the right
- /// parentheses; when \c getOperator()==OO_Subscript, this is the location
- /// of the right bracket.
- SourceLocation getOperatorLoc() const { return getRParenLoc(); }
- SourceLocation getExprLoc() const LLVM_READONLY {
- OverloadedOperatorKind Operator = getOperator();
- return (Operator < OO_Plus || Operator >= OO_Arrow ||
- Operator == OO_PlusPlus || Operator == OO_MinusMinus)
- ? getBeginLoc()
- : getOperatorLoc();
- }
- SourceLocation getBeginLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
- SourceRange getSourceRange() const { return Range; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXOperatorCallExprClass;
- }
- };
- /// Represents a call to a member function that
- /// may be written either with member call syntax (e.g., "obj.func()"
- /// or "objptr->func()") or with normal function-call syntax
- /// ("func()") within a member function that ends up calling a member
- /// function. The callee in either case is a MemberExpr that contains
- /// both the object argument and the member function, while the
- /// arguments are the arguments within the parentheses (not including
- /// the object argument).
- class CXXMemberCallExpr final : public CallExpr {
- // CXXMemberCallExpr has some trailing objects belonging
- // to CallExpr. See CallExpr for the details.
- CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
- ExprValueKind VK, SourceLocation RP,
- FPOptionsOverride FPOptions, unsigned MinNumArgs);
- CXXMemberCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
- public:
- static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
- ArrayRef<Expr *> Args, QualType Ty,
- ExprValueKind VK, SourceLocation RP,
- FPOptionsOverride FPFeatures,
- unsigned MinNumArgs = 0);
- static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
- bool HasFPFeatures, EmptyShell Empty);
- /// Retrieve the implicit object argument for the member call.
- ///
- /// For example, in "x.f(5)", this returns the sub-expression "x".
- Expr *getImplicitObjectArgument() const;
- /// Retrieve the type of the object argument.
- ///
- /// Note that this always returns a non-pointer type.
- QualType getObjectType() const;
- /// Retrieve the declaration of the called method.
- CXXMethodDecl *getMethodDecl() const;
- /// Retrieve the CXXRecordDecl for the underlying type of
- /// the implicit object argument.
- ///
- /// Note that this is may not be the same declaration as that of the class
- /// context of the CXXMethodDecl which this function is calling.
- /// FIXME: Returns 0 for member pointer call exprs.
- CXXRecordDecl *getRecordDecl() const;
- SourceLocation getExprLoc() const LLVM_READONLY {
- SourceLocation CLoc = getCallee()->getExprLoc();
- if (CLoc.isValid())
- return CLoc;
- return getBeginLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXMemberCallExprClass;
- }
- };
- /// Represents a call to a CUDA kernel function.
- class CUDAKernelCallExpr final : public CallExpr {
- friend class ASTStmtReader;
- enum { CONFIG, END_PREARG };
- // CUDAKernelCallExpr has some trailing objects belonging
- // to CallExpr. See CallExpr for the details.
- CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args,
- QualType Ty, ExprValueKind VK, SourceLocation RP,
- FPOptionsOverride FPFeatures, unsigned MinNumArgs);
- CUDAKernelCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
- public:
- static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
- CallExpr *Config, ArrayRef<Expr *> Args,
- QualType Ty, ExprValueKind VK,
- SourceLocation RP,
- FPOptionsOverride FPFeatures,
- unsigned MinNumArgs = 0);
- static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx,
- unsigned NumArgs, bool HasFPFeatures,
- EmptyShell Empty);
- const CallExpr *getConfig() const {
- return cast_or_null<CallExpr>(getPreArg(CONFIG));
- }
- CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CUDAKernelCallExprClass;
- }
- };
- /// A rewritten comparison expression that was originally written using
- /// operator syntax.
- ///
- /// In C++20, the following rewrites are performed:
- /// - <tt>a == b</tt> -> <tt>b == a</tt>
- /// - <tt>a != b</tt> -> <tt>!(a == b)</tt>
- /// - <tt>a != b</tt> -> <tt>!(b == a)</tt>
- /// - For \c \@ in \c <, \c <=, \c >, \c >=, \c <=>:
- /// - <tt>a @ b</tt> -> <tt>(a <=> b) @ 0</tt>
- /// - <tt>a @ b</tt> -> <tt>0 @ (b <=> a)</tt>
- ///
- /// This expression provides access to both the original syntax and the
- /// rewritten expression.
- ///
- /// Note that the rewritten calls to \c ==, \c <=>, and \c \@ are typically
- /// \c CXXOperatorCallExprs, but could theoretically be \c BinaryOperators.
- class CXXRewrittenBinaryOperator : public Expr {
- friend class ASTStmtReader;
- /// The rewritten semantic form.
- Stmt *SemanticForm;
- public:
- CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed)
- : Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(),
- SemanticForm->getValueKind(), SemanticForm->getObjectKind()),
- SemanticForm(SemanticForm) {
- CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed;
- setDependence(computeDependence(this));
- }
- CXXRewrittenBinaryOperator(EmptyShell Empty)
- : Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {}
- /// Get an equivalent semantic form for this expression.
- Expr *getSemanticForm() { return cast<Expr>(SemanticForm); }
- const Expr *getSemanticForm() const { return cast<Expr>(SemanticForm); }
- struct DecomposedForm {
- /// The original opcode, prior to rewriting.
- BinaryOperatorKind Opcode;
- /// The original left-hand side.
- const Expr *LHS;
- /// The original right-hand side.
- const Expr *RHS;
- /// The inner \c == or \c <=> operator expression.
- const Expr *InnerBinOp;
- };
- /// Decompose this operator into its syntactic form.
- DecomposedForm getDecomposedForm() const LLVM_READONLY;
- /// Determine whether this expression was rewritten in reverse form.
- bool isReversed() const { return CXXRewrittenBinaryOperatorBits.IsReversed; }
- BinaryOperatorKind getOperator() const { return getDecomposedForm().Opcode; }
- BinaryOperatorKind getOpcode() const { return getOperator(); }
- static StringRef getOpcodeStr(BinaryOperatorKind Op) {
- return BinaryOperator::getOpcodeStr(Op);
- }
- StringRef getOpcodeStr() const {
- return BinaryOperator::getOpcodeStr(getOpcode());
- }
- bool isComparisonOp() const { return true; }
- bool isAssignmentOp() const { return false; }
- const Expr *getLHS() const { return getDecomposedForm().LHS; }
- const Expr *getRHS() const { return getDecomposedForm().RHS; }
- SourceLocation getOperatorLoc() const LLVM_READONLY {
- return getDecomposedForm().InnerBinOp->getExprLoc();
- }
- SourceLocation getExprLoc() const LLVM_READONLY { return getOperatorLoc(); }
- /// Compute the begin and end locations from the decomposed form.
- /// The locations of the semantic form are not reliable if this is
- /// a reversed expression.
- //@{
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return getDecomposedForm().LHS->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return getDecomposedForm().RHS->getEndLoc();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- DecomposedForm DF = getDecomposedForm();
- return SourceRange(DF.LHS->getBeginLoc(), DF.RHS->getEndLoc());
- }
- //@}
- child_range children() {
- return child_range(&SemanticForm, &SemanticForm + 1);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXRewrittenBinaryOperatorClass;
- }
- };
- /// Abstract class common to all of the C++ "named"/"keyword" casts.
- ///
- /// This abstract class is inherited by all of the classes
- /// representing "named" casts: CXXStaticCastExpr for \c static_cast,
- /// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for
- /// reinterpret_cast, CXXConstCastExpr for \c const_cast and
- /// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL).
- class CXXNamedCastExpr : public ExplicitCastExpr {
- private:
- // the location of the casting op
- SourceLocation Loc;
- // the location of the right parenthesis
- SourceLocation RParenLoc;
- // range for '<' '>'
- SourceRange AngleBrackets;
- protected:
- friend class ASTStmtReader;
- CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind,
- Expr *op, unsigned PathSize, bool HasFPFeatures,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc, SourceRange AngleBrackets)
- : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, HasFPFeatures,
- writtenTy),
- Loc(l), RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
- explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
- bool HasFPFeatures)
- : ExplicitCastExpr(SC, Shell, PathSize, HasFPFeatures) {}
- public:
- const char *getCastName() const;
- /// Retrieve the location of the cast operator keyword, e.g.,
- /// \c static_cast.
- SourceLocation getOperatorLoc() const { return Loc; }
- /// Retrieve the location of the closing parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
- SourceRange getAngleBrackets() const LLVM_READONLY { return AngleBrackets; }
- static bool classof(const Stmt *T) {
- switch (T->getStmtClass()) {
- case CXXStaticCastExprClass:
- case CXXDynamicCastExprClass:
- case CXXReinterpretCastExprClass:
- case CXXConstCastExprClass:
- case CXXAddrspaceCastExprClass:
- return true;
- default:
- return false;
- }
- }
- };
- /// A C++ \c static_cast expression (C++ [expr.static.cast]).
- ///
- /// This expression node represents a C++ static cast, e.g.,
- /// \c static_cast<int>(1.0).
- class CXXStaticCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *,
- FPOptionsOverride> {
- CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
- unsigned pathSize, TypeSourceInfo *writtenTy,
- FPOptionsOverride FPO, SourceLocation l,
- SourceLocation RParenLoc, SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
- FPO.requiresTrailingStorage(), writtenTy, l, RParenLoc,
- AngleBrackets) {
- if (hasStoredFPFeatures())
- *getTrailingFPFeatures() = FPO;
- }
- explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize,
- bool HasFPFeatures)
- : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize,
- HasFPFeatures) {}
- unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
- return path_size();
- }
- public:
- friend class CastExpr;
- friend TrailingObjects;
- static CXXStaticCastExpr *
- Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K,
- Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written,
- FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned PathSize, bool hasFPFeatures);
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXStaticCastExprClass;
- }
- };
- /// A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]).
- ///
- /// This expression node represents a dynamic cast, e.g.,
- /// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time
- /// check to determine how to perform the type conversion.
- class CXXDynamicCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
- CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op,
- unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
- /*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
- AngleBrackets) {}
- explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize,
- /*HasFPFeatures*/ false) {}
- public:
- friend class CastExpr;
- friend TrailingObjects;
- static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind, Expr *Op,
- const CXXCastPath *Path,
- TypeSourceInfo *Written, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXDynamicCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
- bool isAlwaysNull() const;
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDynamicCastExprClass;
- }
- };
- /// A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]).
- ///
- /// This expression node represents a reinterpret cast, e.g.,
- /// @c reinterpret_cast<int>(VoidPtr).
- ///
- /// A reinterpret_cast provides a differently-typed view of a value but
- /// (in Clang, as in most C++ implementations) performs no actual work at
- /// run time.
- class CXXReinterpretCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXReinterpretCastExpr,
- CXXBaseSpecifier *> {
- CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
- unsigned pathSize, TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation RParenLoc,
- SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
- pathSize, /*HasFPFeatures*/ false, writtenTy, l,
- RParenLoc, AngleBrackets) {}
- CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize,
- /*HasFPFeatures*/ false) {}
- public:
- friend class CastExpr;
- friend TrailingObjects;
- static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, CastKind Kind,
- Expr *Op, const CXXCastPath *Path,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXReinterpretCastExpr *CreateEmpty(const ASTContext &Context,
- unsigned pathSize);
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXReinterpretCastExprClass;
- }
- };
- /// A C++ \c const_cast expression (C++ [expr.const.cast]).
- ///
- /// This expression node represents a const cast, e.g.,
- /// \c const_cast<char*>(PtrToConstChar).
- ///
- /// A const_cast can remove type qualifiers but does not change the underlying
- /// value.
- class CXXConstCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> {
- CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc, SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0,
- /*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
- AngleBrackets) {}
- explicit CXXConstCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0,
- /*HasFPFeatures*/ false) {}
- public:
- friend class CastExpr;
- friend TrailingObjects;
- static CXXConstCastExpr *Create(const ASTContext &Context, QualType T,
- ExprValueKind VK, Expr *Op,
- TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc,
- SourceRange AngleBrackets);
- static CXXConstCastExpr *CreateEmpty(const ASTContext &Context);
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstCastExprClass;
- }
- };
- /// A C++ addrspace_cast expression (currently only enabled for OpenCL).
- ///
- /// This expression node represents a cast between pointers to objects in
- /// different address spaces e.g.,
- /// \c addrspace_cast<global int*>(PtrToGenericInt).
- ///
- /// A addrspace_cast can cast address space type qualifiers but does not change
- /// the underlying value.
- class CXXAddrspaceCastExpr final
- : public CXXNamedCastExpr,
- private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> {
- CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l,
- SourceLocation RParenLoc, SourceRange AngleBrackets)
- : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0,
- /*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
- AngleBrackets) {}
- explicit CXXAddrspaceCastExpr(EmptyShell Empty)
- : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0,
- /*HasFPFeatures*/ false) {}
- public:
- friend class CastExpr;
- friend TrailingObjects;
- static CXXAddrspaceCastExpr *
- Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind,
- Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L,
- SourceLocation RParenLoc, SourceRange AngleBrackets);
- static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context);
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXAddrspaceCastExprClass;
- }
- };
- /// A call to a literal operator (C++11 [over.literal])
- /// written as a user-defined literal (C++11 [lit.ext]).
- ///
- /// Represents a user-defined literal, e.g. "foo"_bar or 1.23_xyz. While this
- /// is semantically equivalent to a normal call, this AST node provides better
- /// information about the syntactic representation of the literal.
- ///
- /// Since literal operators are never found by ADL and can only be declared at
- /// namespace scope, a user-defined literal is never dependent.
- class UserDefinedLiteral final : public CallExpr {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- /// The location of a ud-suffix within the literal.
- SourceLocation UDSuffixLoc;
- // UserDefinedLiteral has some trailing objects belonging
- // to CallExpr. See CallExpr for the details.
- UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
- ExprValueKind VK, SourceLocation LitEndLoc,
- SourceLocation SuffixLoc, FPOptionsOverride FPFeatures);
- UserDefinedLiteral(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
- public:
- static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn,
- ArrayRef<Expr *> Args, QualType Ty,
- ExprValueKind VK, SourceLocation LitEndLoc,
- SourceLocation SuffixLoc,
- FPOptionsOverride FPFeatures);
- static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx,
- unsigned NumArgs, bool HasFPOptions,
- EmptyShell Empty);
- /// The kind of literal operator which is invoked.
- enum LiteralOperatorKind {
- /// Raw form: operator "" X (const char *)
- LOK_Raw,
- /// Raw form: operator "" X<cs...> ()
- LOK_Template,
- /// operator "" X (unsigned long long)
- LOK_Integer,
- /// operator "" X (long double)
- LOK_Floating,
- /// operator "" X (const CharT *, size_t)
- LOK_String,
- /// operator "" X (CharT)
- LOK_Character
- };
- /// Returns the kind of literal operator invocation
- /// which this expression represents.
- LiteralOperatorKind getLiteralOperatorKind() const;
- /// If this is not a raw user-defined literal, get the
- /// underlying cooked literal (representing the literal with the suffix
- /// removed).
- Expr *getCookedLiteral();
- const Expr *getCookedLiteral() const {
- return const_cast<UserDefinedLiteral*>(this)->getCookedLiteral();
- }
- SourceLocation getBeginLoc() const {
- if (getLiteralOperatorKind() == LOK_Template)
- return getRParenLoc();
- return getArg(0)->getBeginLoc();
- }
- SourceLocation getEndLoc() const { return getRParenLoc(); }
- /// Returns the location of a ud-suffix in the expression.
- ///
- /// For a string literal, there may be multiple identical suffixes. This
- /// returns the first.
- SourceLocation getUDSuffixLoc() const { return UDSuffixLoc; }
- /// Returns the ud-suffix specified for this literal.
- const IdentifierInfo *getUDSuffix() const;
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == UserDefinedLiteralClass;
- }
- };
- /// A boolean literal, per ([C++ lex.bool] Boolean literals).
- class CXXBoolLiteralExpr : public Expr {
- public:
- CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc)
- : Expr(CXXBoolLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
- CXXBoolLiteralExprBits.Value = Val;
- CXXBoolLiteralExprBits.Loc = Loc;
- setDependence(ExprDependence::None);
- }
- explicit CXXBoolLiteralExpr(EmptyShell Empty)
- : Expr(CXXBoolLiteralExprClass, Empty) {}
- bool getValue() const { return CXXBoolLiteralExprBits.Value; }
- void setValue(bool V) { CXXBoolLiteralExprBits.Value = V; }
- SourceLocation getBeginLoc() const { return getLocation(); }
- SourceLocation getEndLoc() const { return getLocation(); }
- SourceLocation getLocation() const { return CXXBoolLiteralExprBits.Loc; }
- void setLocation(SourceLocation L) { CXXBoolLiteralExprBits.Loc = L; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBoolLiteralExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// The null pointer literal (C++11 [lex.nullptr])
- ///
- /// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
- class CXXNullPtrLiteralExpr : public Expr {
- public:
- CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
- : Expr(CXXNullPtrLiteralExprClass, Ty, VK_PRValue, OK_Ordinary) {
- CXXNullPtrLiteralExprBits.Loc = Loc;
- setDependence(ExprDependence::None);
- }
- explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
- : Expr(CXXNullPtrLiteralExprClass, Empty) {}
- SourceLocation getBeginLoc() const { return getLocation(); }
- SourceLocation getEndLoc() const { return getLocation(); }
- SourceLocation getLocation() const { return CXXNullPtrLiteralExprBits.Loc; }
- void setLocation(SourceLocation L) { CXXNullPtrLiteralExprBits.Loc = L; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNullPtrLiteralExprClass;
- }
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Implicit construction of a std::initializer_list<T> object from an
- /// array temporary within list-initialization (C++11 [dcl.init.list]p5).
- class CXXStdInitializerListExpr : public Expr {
- Stmt *SubExpr = nullptr;
- CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty) {}
- public:
- friend class ASTReader;
- friend class ASTStmtReader;
- CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
- : Expr(CXXStdInitializerListExprClass, Ty, VK_PRValue, OK_Ordinary),
- SubExpr(SubExpr) {
- setDependence(computeDependence(this));
- }
- Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); }
- const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return SubExpr->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return SubExpr->getEndLoc();
- }
- /// Retrieve the source range of the expression.
- SourceRange getSourceRange() const LLVM_READONLY {
- return SubExpr->getSourceRange();
- }
- static bool classof(const Stmt *S) {
- return S->getStmtClass() == CXXStdInitializerListExprClass;
- }
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
- const_child_range children() const {
- return const_child_range(&SubExpr, &SubExpr + 1);
- }
- };
- /// A C++ \c typeid expression (C++ [expr.typeid]), which gets
- /// the \c type_info that corresponds to the supplied type, or the (possibly
- /// dynamic) type of the supplied expression.
- ///
- /// This represents code like \c typeid(int) or \c typeid(*objPtr)
- class CXXTypeidExpr : public Expr {
- friend class ASTStmtReader;
- private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- SourceRange Range;
- public:
- CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
- Range(R) {
- setDependence(computeDependence(this));
- }
- CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
- : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
- Range(R) {
- setDependence(computeDependence(this));
- }
- CXXTypeidExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXTypeidExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
- /// Determine whether this typeid has a type operand which is potentially
- /// evaluated, per C++11 [expr.typeid]p3.
- bool isPotentiallyEvaluated() const;
- /// Best-effort check if the expression operand refers to a most derived
- /// object. This is not a strong guarantee.
- bool isMostDerived(ASTContext &Context) const;
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
- /// Retrieves the type operand of this typeid() expression after
- /// various required adjustments (removing reference types, cv-qualifiers).
- QualType getTypeOperand(ASTContext &Context) const;
- /// Retrieve source information for the type operand.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
- SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTypeidExprClass;
- }
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- auto **begin = reinterpret_cast<Stmt **>(&Operand);
- return child_range(begin, begin + 1);
- }
- const_child_range children() const {
- if (isTypeOperand())
- return const_child_range(const_child_iterator(), const_child_iterator());
- auto **begin =
- reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand);
- return const_child_range(begin, begin + 1);
- }
- };
- /// A member reference to an MSPropertyDecl.
- ///
- /// This expression always has pseudo-object type, and therefore it is
- /// typically not encountered in a fully-typechecked expression except
- /// within the syntactic form of a PseudoObjectExpr.
- class MSPropertyRefExpr : public Expr {
- Expr *BaseExpr;
- MSPropertyDecl *TheDecl;
- SourceLocation MemberLoc;
- bool IsArrow;
- NestedNameSpecifierLoc QualifierLoc;
- public:
- friend class ASTStmtReader;
- MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow,
- QualType ty, ExprValueKind VK,
- NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc)
- : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr),
- TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow),
- QualifierLoc(qualifierLoc) {
- setDependence(computeDependence(this));
- }
- MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {}
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getBeginLoc(), getEndLoc());
- }
- bool isImplicitAccess() const {
- return getBaseExpr() && getBaseExpr()->isImplicitCXXThis();
- }
- SourceLocation getBeginLoc() const {
- if (!isImplicitAccess())
- return BaseExpr->getBeginLoc();
- else if (QualifierLoc)
- return QualifierLoc.getBeginLoc();
- else
- return MemberLoc;
- }
- SourceLocation getEndLoc() const { return getMemberLoc(); }
- child_range children() {
- return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
- }
- const_child_range children() const {
- auto Children = const_cast<MSPropertyRefExpr *>(this)->children();
- return const_child_range(Children.begin(), Children.end());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertyRefExprClass;
- }
- Expr *getBaseExpr() const { return BaseExpr; }
- MSPropertyDecl *getPropertyDecl() const { return TheDecl; }
- bool isArrow() const { return IsArrow; }
- SourceLocation getMemberLoc() const { return MemberLoc; }
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- };
- /// MS property subscript expression.
- /// MSVC supports 'property' attribute and allows to apply it to the
- /// declaration of an empty array in a class or structure definition.
- /// For example:
- /// \code
- /// __declspec(property(get=GetX, put=PutX)) int x[];
- /// \endcode
- /// The above statement indicates that x[] can be used with one or more array
- /// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and
- /// p->x[a][b] = i will be turned into p->PutX(a, b, i).
- /// This is a syntactic pseudo-object expression.
- class MSPropertySubscriptExpr : public Expr {
- friend class ASTStmtReader;
- enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 };
- Stmt *SubExprs[NUM_SUBEXPRS];
- SourceLocation RBracketLoc;
- void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; }
- void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; }
- public:
- MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK,
- ExprObjectKind OK, SourceLocation RBracketLoc)
- : Expr(MSPropertySubscriptExprClass, Ty, VK, OK),
- RBracketLoc(RBracketLoc) {
- SubExprs[BASE_EXPR] = Base;
- SubExprs[IDX_EXPR] = Idx;
- setDependence(computeDependence(this));
- }
- /// Create an empty array subscript expression.
- explicit MSPropertySubscriptExpr(EmptyShell Shell)
- : Expr(MSPropertySubscriptExprClass, Shell) {}
- Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); }
- const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); }
- Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); }
- const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return getBase()->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }
- SourceLocation getRBracketLoc() const { return RBracketLoc; }
- void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
- SourceLocation getExprLoc() const LLVM_READONLY {
- return getBase()->getExprLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSPropertySubscriptExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
- }
- const_child_range children() const {
- return const_child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
- }
- };
- /// A Microsoft C++ @c __uuidof expression, which gets
- /// the _GUID that corresponds to the supplied type or expression.
- ///
- /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr)
- class CXXUuidofExpr : public Expr {
- friend class ASTStmtReader;
- private:
- llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
- MSGuidDecl *Guid;
- SourceRange Range;
- public:
- CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid,
- SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
- Guid(Guid), Range(R) {
- setDependence(computeDependence(this));
- }
- CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R)
- : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand),
- Guid(Guid), Range(R) {
- setDependence(computeDependence(this));
- }
- CXXUuidofExpr(EmptyShell Empty, bool isExpr)
- : Expr(CXXUuidofExprClass, Empty) {
- if (isExpr)
- Operand = (Expr*)nullptr;
- else
- Operand = (TypeSourceInfo*)nullptr;
- }
- bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
- /// Retrieves the type operand of this __uuidof() expression after
- /// various required adjustments (removing reference types, cv-qualifiers).
- QualType getTypeOperand(ASTContext &Context) const;
- /// Retrieve source information for the type operand.
- TypeSourceInfo *getTypeOperandSourceInfo() const {
- assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
- return Operand.get<TypeSourceInfo *>();
- }
- Expr *getExprOperand() const {
- assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)");
- return static_cast<Expr*>(Operand.get<Stmt *>());
- }
- MSGuidDecl *getGuidDecl() const { return Guid; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
- SourceRange getSourceRange() const LLVM_READONLY { return Range; }
- void setSourceRange(SourceRange R) { Range = R; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUuidofExprClass;
- }
- // Iterators
- child_range children() {
- if (isTypeOperand())
- return child_range(child_iterator(), child_iterator());
- auto **begin = reinterpret_cast<Stmt **>(&Operand);
- return child_range(begin, begin + 1);
- }
- const_child_range children() const {
- if (isTypeOperand())
- return const_child_range(const_child_iterator(), const_child_iterator());
- auto **begin =
- reinterpret_cast<Stmt **>(&const_cast<CXXUuidofExpr *>(this)->Operand);
- return const_child_range(begin, begin + 1);
- }
- };
- /// Represents the \c this expression in C++.
- ///
- /// This is a pointer to the object on which the current member function is
- /// executing (C++ [expr.prim]p3). Example:
- ///
- /// \code
- /// class Foo {
- /// public:
- /// void bar();
- /// void test() { this->bar(); }
- /// };
- /// \endcode
- class CXXThisExpr : public Expr {
- public:
- CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit)
- : Expr(CXXThisExprClass, Ty, VK_PRValue, OK_Ordinary) {
- CXXThisExprBits.IsImplicit = IsImplicit;
- CXXThisExprBits.Loc = L;
- setDependence(computeDependence(this));
- }
- CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
- SourceLocation getLocation() const { return CXXThisExprBits.Loc; }
- void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; }
- SourceLocation getBeginLoc() const { return getLocation(); }
- SourceLocation getEndLoc() const { return getLocation(); }
- bool isImplicit() const { return CXXThisExprBits.IsImplicit; }
- void setImplicit(bool I) { CXXThisExprBits.IsImplicit = I; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThisExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// A C++ throw-expression (C++ [except.throw]).
- ///
- /// This handles 'throw' (for re-throwing the current exception) and
- /// 'throw' assignment-expression. When assignment-expression isn't
- /// present, Op will be null.
- class CXXThrowExpr : public Expr {
- friend class ASTStmtReader;
- /// The optional expression in the throw statement.
- Stmt *Operand;
- public:
- // \p Ty is the void type which is used as the result type of the
- // expression. The \p Loc is the location of the throw keyword.
- // \p Operand is the expression in the throw statement, and can be
- // null if not present.
- CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc,
- bool IsThrownVariableInScope)
- : Expr(CXXThrowExprClass, Ty, VK_PRValue, OK_Ordinary), Operand(Operand) {
- CXXThrowExprBits.ThrowLoc = Loc;
- CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope;
- setDependence(computeDependence(this));
- }
- CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {}
- const Expr *getSubExpr() const { return cast_or_null<Expr>(Operand); }
- Expr *getSubExpr() { return cast_or_null<Expr>(Operand); }
- SourceLocation getThrowLoc() const { return CXXThrowExprBits.ThrowLoc; }
- /// Determines whether the variable thrown by this expression (if any!)
- /// is within the innermost try block.
- ///
- /// This information is required to determine whether the NRVO can apply to
- /// this variable.
- bool isThrownVariableInScope() const {
- return CXXThrowExprBits.IsThrownVariableInScope;
- }
- SourceLocation getBeginLoc() const { return getThrowLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (!getSubExpr())
- return getThrowLoc();
- return getSubExpr()->getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXThrowExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(&Operand, Operand ? &Operand + 1 : &Operand);
- }
- const_child_range children() const {
- return const_child_range(&Operand, Operand ? &Operand + 1 : &Operand);
- }
- };
- /// A default argument (C++ [dcl.fct.default]).
- ///
- /// This wraps up a function call argument that was created from the
- /// corresponding parameter's default argument, when the call did not
- /// explicitly supply arguments for all of the parameters.
- class CXXDefaultArgExpr final : public Expr {
- friend class ASTStmtReader;
- /// The parameter whose default is being used.
- ParmVarDecl *Param;
- /// The context where the default argument expression was used.
- DeclContext *UsedContext;
- CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
- DeclContext *UsedContext)
- : Expr(SC,
- Param->hasUnparsedDefaultArg()
- ? Param->getType().getNonReferenceType()
- : Param->getDefaultArg()->getType(),
- Param->getDefaultArg()->getValueKind(),
- Param->getDefaultArg()->getObjectKind()),
- Param(Param), UsedContext(UsedContext) {
- CXXDefaultArgExprBits.Loc = Loc;
- setDependence(computeDependence(this));
- }
- public:
- CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
- // \p Param is the parameter whose default argument is used by this
- // expression.
- static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param,
- DeclContext *UsedContext) {
- return new (C)
- CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext);
- }
- // Retrieve the parameter that the argument was created from.
- const ParmVarDecl *getParam() const { return Param; }
- ParmVarDecl *getParam() { return Param; }
- // Retrieve the actual argument to the function call.
- const Expr *getExpr() const { return getParam()->getDefaultArg(); }
- Expr *getExpr() { return getParam()->getDefaultArg(); }
- const DeclContext *getUsedContext() const { return UsedContext; }
- DeclContext *getUsedContext() { return UsedContext; }
- /// Retrieve the location where this default argument was actually used.
- SourceLocation getUsedLocation() const { return CXXDefaultArgExprBits.Loc; }
- /// Default argument expressions have no representation in the
- /// source, so they have an empty source range.
- SourceLocation getBeginLoc() const { return SourceLocation(); }
- SourceLocation getEndLoc() const { return SourceLocation(); }
- SourceLocation getExprLoc() const { return getUsedLocation(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultArgExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// A use of a default initializer in a constructor or in aggregate
- /// initialization.
- ///
- /// This wraps a use of a C++ default initializer (technically,
- /// a brace-or-equal-initializer for a non-static data member) when it
- /// is implicitly used in a mem-initializer-list in a constructor
- /// (C++11 [class.base.init]p8) or in aggregate initialization
- /// (C++1y [dcl.init.aggr]p7).
- class CXXDefaultInitExpr : public Expr {
- friend class ASTReader;
- friend class ASTStmtReader;
- /// The field whose default is being used.
- FieldDecl *Field;
- /// The context where the default initializer expression was used.
- DeclContext *UsedContext;
- CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
- FieldDecl *Field, QualType Ty, DeclContext *UsedContext);
- CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
- public:
- /// \p Field is the non-static data member whose default initializer is used
- /// by this expression.
- static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc,
- FieldDecl *Field, DeclContext *UsedContext) {
- return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext);
- }
- /// Get the field whose initializer will be used.
- FieldDecl *getField() { return Field; }
- const FieldDecl *getField() const { return Field; }
- /// Get the initialization expression that will be used.
- const Expr *getExpr() const {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
- Expr *getExpr() {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
- }
- const DeclContext *getUsedContext() const { return UsedContext; }
- DeclContext *getUsedContext() { return UsedContext; }
- /// Retrieve the location where this default initializer expression was
- /// actually used.
- SourceLocation getUsedLocation() const { return getBeginLoc(); }
- SourceLocation getBeginLoc() const { return CXXDefaultInitExprBits.Loc; }
- SourceLocation getEndLoc() const { return CXXDefaultInitExprBits.Loc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDefaultInitExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Represents a C++ temporary.
- class CXXTemporary {
- /// The destructor that needs to be called.
- const CXXDestructorDecl *Destructor;
- explicit CXXTemporary(const CXXDestructorDecl *destructor)
- : Destructor(destructor) {}
- public:
- static CXXTemporary *Create(const ASTContext &C,
- const CXXDestructorDecl *Destructor);
- const CXXDestructorDecl *getDestructor() const { return Destructor; }
- void setDestructor(const CXXDestructorDecl *Dtor) {
- Destructor = Dtor;
- }
- };
- /// Represents binding an expression to a temporary.
- ///
- /// This ensures the destructor is called for the temporary. It should only be
- /// needed for non-POD, non-trivially destructable class types. For example:
- ///
- /// \code
- /// struct S {
- /// S() { } // User defined constructor makes S non-POD.
- /// ~S() { } // User defined destructor makes it non-trivial.
- /// };
- /// void test() {
- /// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr.
- /// }
- /// \endcode
- class CXXBindTemporaryExpr : public Expr {
- CXXTemporary *Temp = nullptr;
- Stmt *SubExpr = nullptr;
- CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr)
- : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_PRValue,
- OK_Ordinary),
- Temp(temp), SubExpr(SubExpr) {
- setDependence(computeDependence(this));
- }
- public:
- CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty) {}
- static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
- Expr* SubExpr);
- CXXTemporary *getTemporary() { return Temp; }
- const CXXTemporary *getTemporary() const { return Temp; }
- void setTemporary(CXXTemporary *T) { Temp = T; }
- const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
- Expr *getSubExpr() { return cast<Expr>(SubExpr); }
- void setSubExpr(Expr *E) { SubExpr = E; }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return SubExpr->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return SubExpr->getEndLoc();
- }
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXBindTemporaryExprClass;
- }
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
- const_child_range children() const {
- return const_child_range(&SubExpr, &SubExpr + 1);
- }
- };
- /// Represents a call to a C++ constructor.
- class CXXConstructExpr : public Expr {
- friend class ASTStmtReader;
- public:
- enum ConstructionKind {
- CK_Complete,
- CK_NonVirtualBase,
- CK_VirtualBase,
- CK_Delegating
- };
- private:
- /// A pointer to the constructor which will be ultimately called.
- CXXConstructorDecl *Constructor;
- SourceRange ParenOrBraceRange;
- /// The number of arguments.
- unsigned NumArgs;
- // We would like to stash the arguments of the constructor call after
- // CXXConstructExpr. However CXXConstructExpr is used as a base class of
- // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects
- // impossible.
- //
- // Instead we manually stash the trailing object after the full object
- // containing CXXConstructExpr (that is either CXXConstructExpr or
- // CXXTemporaryObjectExpr).
- //
- // The trailing objects are:
- //
- // * An array of getNumArgs() "Stmt *" for the arguments of the
- // constructor call.
- /// Return a pointer to the start of the trailing arguments.
- /// Defined just after CXXTemporaryObjectExpr.
- inline Stmt **getTrailingArgs();
- const Stmt *const *getTrailingArgs() const {
- return const_cast<CXXConstructExpr *>(this)->getTrailingArgs();
- }
- protected:
- /// Build a C++ construction expression.
- CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc,
- CXXConstructorDecl *Ctor, bool Elidable,
- ArrayRef<Expr *> Args, bool HadMultipleCandidates,
- bool ListInitialization, bool StdInitListInitialization,
- bool ZeroInitialization, ConstructionKind ConstructKind,
- SourceRange ParenOrBraceRange);
- /// Build an empty C++ construction expression.
- CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs);
- /// Return the size in bytes of the trailing objects. Used by
- /// CXXTemporaryObjectExpr to allocate the right amount of storage.
- static unsigned sizeOfTrailingObjects(unsigned NumArgs) {
- return NumArgs * sizeof(Stmt *);
- }
- public:
- /// Create a C++ construction expression.
- static CXXConstructExpr *
- Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
- CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
- bool HadMultipleCandidates, bool ListInitialization,
- bool StdInitListInitialization, bool ZeroInitialization,
- ConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
- /// Create an empty C++ construction expression.
- static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
- /// Get the constructor that this expression will (ultimately) call.
- CXXConstructorDecl *getConstructor() const { return Constructor; }
- SourceLocation getLocation() const { return CXXConstructExprBits.Loc; }
- void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; }
- /// Whether this construction is elidable.
- bool isElidable() const { return CXXConstructExprBits.Elidable; }
- void setElidable(bool E) { CXXConstructExprBits.Elidable = E; }
- /// Whether the referred constructor was resolved from
- /// an overloaded set having size greater than 1.
- bool hadMultipleCandidates() const {
- return CXXConstructExprBits.HadMultipleCandidates;
- }
- void setHadMultipleCandidates(bool V) {
- CXXConstructExprBits.HadMultipleCandidates = V;
- }
- /// Whether this constructor call was written as list-initialization.
- bool isListInitialization() const {
- return CXXConstructExprBits.ListInitialization;
- }
- void setListInitialization(bool V) {
- CXXConstructExprBits.ListInitialization = V;
- }
- /// Whether this constructor call was written as list-initialization,
- /// but was interpreted as forming a std::initializer_list<T> from the list
- /// and passing that as a single constructor argument.
- /// See C++11 [over.match.list]p1 bullet 1.
- bool isStdInitListInitialization() const {
- return CXXConstructExprBits.StdInitListInitialization;
- }
- void setStdInitListInitialization(bool V) {
- CXXConstructExprBits.StdInitListInitialization = V;
- }
- /// Whether this construction first requires
- /// zero-initialization before the initializer is called.
- bool requiresZeroInitialization() const {
- return CXXConstructExprBits.ZeroInitialization;
- }
- void setRequiresZeroInitialization(bool ZeroInit) {
- CXXConstructExprBits.ZeroInitialization = ZeroInit;
- }
- /// Determine whether this constructor is actually constructing
- /// a base class (rather than a complete object).
- ConstructionKind getConstructionKind() const {
- return static_cast<ConstructionKind>(CXXConstructExprBits.ConstructionKind);
- }
- void setConstructionKind(ConstructionKind CK) {
- CXXConstructExprBits.ConstructionKind = CK;
- }
- using arg_iterator = ExprIterator;
- using const_arg_iterator = ConstExprIterator;
- using arg_range = llvm::iterator_range<arg_iterator>;
- using const_arg_range = llvm::iterator_range<const_arg_iterator>;
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- const_arg_range arguments() const {
- return const_arg_range(arg_begin(), arg_end());
- }
- arg_iterator arg_begin() { return getTrailingArgs(); }
- arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
- const_arg_iterator arg_begin() const { return getTrailingArgs(); }
- const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
- Expr **getArgs() { return reinterpret_cast<Expr **>(getTrailingArgs()); }
- const Expr *const *getArgs() const {
- return reinterpret_cast<const Expr *const *>(getTrailingArgs());
- }
- /// Return the number of arguments to the constructor call.
- unsigned getNumArgs() const { return NumArgs; }
- /// Return the specified argument.
- Expr *getArg(unsigned Arg) {
- assert(Arg < getNumArgs() && "Arg access out of range!");
- return getArgs()[Arg];
- }
- const Expr *getArg(unsigned Arg) const {
- assert(Arg < getNumArgs() && "Arg access out of range!");
- return getArgs()[Arg];
- }
- /// Set the specified argument.
- void setArg(unsigned Arg, Expr *ArgExpr) {
- assert(Arg < getNumArgs() && "Arg access out of range!");
- getArgs()[Arg] = ArgExpr;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY;
- SourceLocation getEndLoc() const LLVM_READONLY;
- SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
- void setParenOrBraceRange(SourceRange Range) { ParenOrBraceRange = Range; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXConstructExprClass ||
- T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs());
- }
- const_child_range children() const {
- auto Children = const_cast<CXXConstructExpr *>(this)->children();
- return const_child_range(Children.begin(), Children.end());
- }
- };
- /// Represents a call to an inherited base class constructor from an
- /// inheriting constructor. This call implicitly forwards the arguments from
- /// the enclosing context (an inheriting constructor) to the specified inherited
- /// base class constructor.
- class CXXInheritedCtorInitExpr : public Expr {
- private:
- CXXConstructorDecl *Constructor = nullptr;
- /// The location of the using declaration.
- SourceLocation Loc;
- /// Whether this is the construction of a virtual base.
- unsigned ConstructsVirtualBase : 1;
- /// Whether the constructor is inherited from a virtual base class of the
- /// class that we construct.
- unsigned InheritedFromVirtualBase : 1;
- public:
- friend class ASTStmtReader;
- /// Construct a C++ inheriting construction expression.
- CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T,
- CXXConstructorDecl *Ctor, bool ConstructsVirtualBase,
- bool InheritedFromVirtualBase)
- : Expr(CXXInheritedCtorInitExprClass, T, VK_PRValue, OK_Ordinary),
- Constructor(Ctor), Loc(Loc),
- ConstructsVirtualBase(ConstructsVirtualBase),
- InheritedFromVirtualBase(InheritedFromVirtualBase) {
- assert(!T->isDependentType());
- setDependence(ExprDependence::None);
- }
- /// Construct an empty C++ inheriting construction expression.
- explicit CXXInheritedCtorInitExpr(EmptyShell Empty)
- : Expr(CXXInheritedCtorInitExprClass, Empty),
- ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {}
- /// Get the constructor that this expression will call.
- CXXConstructorDecl *getConstructor() const { return Constructor; }
- /// Determine whether this constructor is actually constructing
- /// a base class (rather than a complete object).
- bool constructsVBase() const { return ConstructsVirtualBase; }
- CXXConstructExpr::ConstructionKind getConstructionKind() const {
- return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase
- : CXXConstructExpr::CK_NonVirtualBase;
- }
- /// Determine whether the inherited constructor is inherited from a
- /// virtual base of the object we construct. If so, we are not responsible
- /// for calling the inherited constructor (the complete object constructor
- /// does that), and so we don't need to pass any arguments.
- bool inheritedFromVBase() const { return InheritedFromVirtualBase; }
- SourceLocation getLocation() const LLVM_READONLY { return Loc; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return Loc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXInheritedCtorInitExprClass;
- }
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Represents an explicit C++ type conversion that uses "functional"
- /// notation (C++ [expr.type.conv]).
- ///
- /// Example:
- /// \code
- /// x = int(0.5);
- /// \endcode
- class CXXFunctionalCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *,
- FPOptionsOverride> {
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
- CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
- TypeSourceInfo *writtenTy, CastKind kind,
- Expr *castExpr, unsigned pathSize,
- FPOptionsOverride FPO, SourceLocation lParenLoc,
- SourceLocation rParenLoc)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr,
- pathSize, FPO.requiresTrailingStorage(), writtenTy),
- LParenLoc(lParenLoc), RParenLoc(rParenLoc) {
- if (hasStoredFPFeatures())
- *getTrailingFPFeatures() = FPO;
- }
- explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize,
- bool HasFPFeatures)
- : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize,
- HasFPFeatures) {}
- unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
- return path_size();
- }
- public:
- friend class CastExpr;
- friend TrailingObjects;
- static CXXFunctionalCastExpr *
- Create(const ASTContext &Context, QualType T, ExprValueKind VK,
- TypeSourceInfo *Written, CastKind Kind, Expr *Op,
- const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc,
- SourceLocation RPLoc);
- static CXXFunctionalCastExpr *
- CreateEmpty(const ASTContext &Context, unsigned PathSize, bool HasFPFeatures);
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- /// Determine whether this expression models list-initialization.
- bool isListInitialization() const { return LParenLoc.isInvalid(); }
- SourceLocation getBeginLoc() const LLVM_READONLY;
- SourceLocation getEndLoc() const LLVM_READONLY;
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFunctionalCastExprClass;
- }
- };
- /// Represents a C++ functional cast expression that builds a
- /// temporary object.
- ///
- /// This expression type represents a C++ "functional" cast
- /// (C++[expr.type.conv]) with N != 1 arguments that invokes a
- /// constructor to build a temporary object. With N == 1 arguments the
- /// functional cast expression will be represented by CXXFunctionalCastExpr.
- /// Example:
- /// \code
- /// struct X { X(int, float); }
- ///
- /// X create_X() {
- /// return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
- /// };
- /// \endcode
- class CXXTemporaryObjectExpr final : public CXXConstructExpr {
- friend class ASTStmtReader;
- // CXXTemporaryObjectExpr has some trailing objects belonging
- // to CXXConstructExpr. See the comment inside CXXConstructExpr
- // for more details.
- TypeSourceInfo *TSI;
- CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty,
- TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
- SourceRange ParenOrBraceRange,
- bool HadMultipleCandidates, bool ListInitialization,
- bool StdInitListInitialization,
- bool ZeroInitialization);
- CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs);
- public:
- static CXXTemporaryObjectExpr *
- Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
- TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
- SourceRange ParenOrBraceRange, bool HadMultipleCandidates,
- bool ListInitialization, bool StdInitListInitialization,
- bool ZeroInitialization);
- static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx,
- unsigned NumArgs);
- TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
- SourceLocation getBeginLoc() const LLVM_READONLY;
- SourceLocation getEndLoc() const LLVM_READONLY;
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXTemporaryObjectExprClass;
- }
- };
- Stmt **CXXConstructExpr::getTrailingArgs() {
- if (auto *E = dyn_cast<CXXTemporaryObjectExpr>(this))
- return reinterpret_cast<Stmt **>(E + 1);
- assert((getStmtClass() == CXXConstructExprClass) &&
- "Unexpected class deriving from CXXConstructExpr!");
- return reinterpret_cast<Stmt **>(this + 1);
- }
- /// A C++ lambda expression, which produces a function object
- /// (of unspecified type) that can be invoked later.
- ///
- /// Example:
- /// \code
- /// void low_pass_filter(std::vector<double> &values, double cutoff) {
- /// values.erase(std::remove_if(values.begin(), values.end(),
- /// [=](double value) { return value > cutoff; });
- /// }
- /// \endcode
- ///
- /// C++11 lambda expressions can capture local variables, either by copying
- /// the values of those local variables at the time the function
- /// object is constructed (not when it is called!) or by holding a
- /// reference to the local variable. These captures can occur either
- /// implicitly or can be written explicitly between the square
- /// brackets ([...]) that start the lambda expression.
- ///
- /// C++1y introduces a new form of "capture" called an init-capture that
- /// includes an initializing expression (rather than capturing a variable),
- /// and which can never occur implicitly.
- class LambdaExpr final : public Expr,
- private llvm::TrailingObjects<LambdaExpr, Stmt *> {
- // LambdaExpr has some data stored in LambdaExprBits.
- /// The source range that covers the lambda introducer ([...]).
- SourceRange IntroducerRange;
- /// The source location of this lambda's capture-default ('=' or '&').
- SourceLocation CaptureDefaultLoc;
- /// The location of the closing brace ('}') that completes
- /// the lambda.
- ///
- /// The location of the brace is also available by looking up the
- /// function call operator in the lambda class. However, it is
- /// stored here to improve the performance of getSourceRange(), and
- /// to avoid having to deserialize the function call operator from a
- /// module file just to determine the source range.
- SourceLocation ClosingBrace;
- /// Construct a lambda expression.
- LambdaExpr(QualType T, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc, bool ExplicitParams,
- bool ExplicitResultType, ArrayRef<Expr *> CaptureInits,
- SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack);
- /// Construct an empty lambda expression.
- LambdaExpr(EmptyShell Empty, unsigned NumCaptures);
- Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); }
- Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); }
- void initBodyIfNeeded() const;
- public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
- /// Construct a new lambda expression.
- static LambdaExpr *
- Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange,
- LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc,
- bool ExplicitParams, bool ExplicitResultType,
- ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace,
- bool ContainsUnexpandedParameterPack);
- /// Construct a new lambda expression that will be deserialized from
- /// an external source.
- static LambdaExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumCaptures);
- /// Determine the default capture kind for this lambda.
- LambdaCaptureDefault getCaptureDefault() const {
- return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault);
- }
- /// Retrieve the location of this lambda's capture-default, if any.
- SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; }
- /// Determine whether one of this lambda's captures is an init-capture.
- bool isInitCapture(const LambdaCapture *Capture) const;
- /// An iterator that walks over the captures of the lambda,
- /// both implicit and explicit.
- using capture_iterator = const LambdaCapture *;
- /// An iterator over a range of lambda captures.
- using capture_range = llvm::iterator_range<capture_iterator>;
- /// Retrieve this lambda's captures.
- capture_range captures() const;
- /// Retrieve an iterator pointing to the first lambda capture.
- capture_iterator capture_begin() const;
- /// Retrieve an iterator pointing past the end of the
- /// sequence of lambda captures.
- capture_iterator capture_end() const;
- /// Determine the number of captures in this lambda.
- unsigned capture_size() const { return LambdaExprBits.NumCaptures; }
- /// Retrieve this lambda's explicit captures.
- capture_range explicit_captures() const;
- /// Retrieve an iterator pointing to the first explicit
- /// lambda capture.
- capture_iterator explicit_capture_begin() const;
- /// Retrieve an iterator pointing past the end of the sequence of
- /// explicit lambda captures.
- capture_iterator explicit_capture_end() const;
- /// Retrieve this lambda's implicit captures.
- capture_range implicit_captures() const;
- /// Retrieve an iterator pointing to the first implicit
- /// lambda capture.
- capture_iterator implicit_capture_begin() const;
- /// Retrieve an iterator pointing past the end of the sequence of
- /// implicit lambda captures.
- capture_iterator implicit_capture_end() const;
- /// Iterator that walks over the capture initialization
- /// arguments.
- using capture_init_iterator = Expr **;
- /// Const iterator that walks over the capture initialization
- /// arguments.
- /// FIXME: This interface is prone to being used incorrectly.
- using const_capture_init_iterator = Expr *const *;
- /// Retrieve the initialization expressions for this lambda's captures.
- llvm::iterator_range<capture_init_iterator> capture_inits() {
- return llvm::make_range(capture_init_begin(), capture_init_end());
- }
- /// Retrieve the initialization expressions for this lambda's captures.
- llvm::iterator_range<const_capture_init_iterator> capture_inits() const {
- return llvm::make_range(capture_init_begin(), capture_init_end());
- }
- /// Retrieve the first initialization argument for this
- /// lambda expression (which initializes the first capture field).
- capture_init_iterator capture_init_begin() {
- return reinterpret_cast<Expr **>(getStoredStmts());
- }
- /// Retrieve the first initialization argument for this
- /// lambda expression (which initializes the first capture field).
- const_capture_init_iterator capture_init_begin() const {
- return reinterpret_cast<Expr *const *>(getStoredStmts());
- }
- /// Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression.
- capture_init_iterator capture_init_end() {
- return capture_init_begin() + capture_size();
- }
- /// Retrieve the iterator pointing one past the last
- /// initialization argument for this lambda expression.
- const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + capture_size();
- }
- /// Retrieve the source range covering the lambda introducer,
- /// which contains the explicit capture list surrounded by square
- /// brackets ([...]).
- SourceRange getIntroducerRange() const { return IntroducerRange; }
- /// Retrieve the class that corresponds to the lambda.
- ///
- /// This is the "closure type" (C++1y [expr.prim.lambda]), and stores the
- /// captures in its fields and provides the various operations permitted
- /// on a lambda (copying, calling).
- CXXRecordDecl *getLambdaClass() const;
- /// Retrieve the function call operator associated with this
- /// lambda expression.
- CXXMethodDecl *getCallOperator() const;
- /// Retrieve the function template call operator associated with this
- /// lambda expression.
- FunctionTemplateDecl *getDependentCallOperator() const;
- /// If this is a generic lambda expression, retrieve the template
- /// parameter list associated with it, or else return null.
- TemplateParameterList *getTemplateParameterList() const;
- /// Get the template parameters were explicitly specified (as opposed to being
- /// invented by use of an auto parameter).
- ArrayRef<NamedDecl *> getExplicitTemplateParameters() const;
- /// Get the trailing requires clause, if any.
- Expr *getTrailingRequiresClause() const;
- /// Whether this is a generic lambda.
- bool isGenericLambda() const { return getTemplateParameterList(); }
- /// Retrieve the body of the lambda. This will be most of the time
- /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping
- /// a \p CompoundStmt. Note that unlike functions, lambda-expressions
- /// cannot have a function-try-block.
- Stmt *getBody() const;
- /// Retrieve the \p CompoundStmt representing the body of the lambda.
- /// This is a convenience function for callers who do not need
- /// to handle node(s) which may wrap a \p CompoundStmt.
- const CompoundStmt *getCompoundStmtBody() const;
- CompoundStmt *getCompoundStmtBody() {
- const auto *ConstThis = this;
- return const_cast<CompoundStmt *>(ConstThis->getCompoundStmtBody());
- }
- /// Determine whether the lambda is mutable, meaning that any
- /// captures values can be modified.
- bool isMutable() const;
- /// Determine whether this lambda has an explicit parameter
- /// list vs. an implicit (empty) parameter list.
- bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; }
- /// Whether this lambda had its result type explicitly specified.
- bool hasExplicitResultType() const {
- return LambdaExprBits.ExplicitResultType;
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LambdaExprClass;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return IntroducerRange.getBegin();
- }
- SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; }
- /// Includes the captures and the body of the lambda.
- child_range children();
- const_child_range children() const;
- };
- /// An expression "T()" which creates a value-initialized rvalue of type
- /// T, which is a non-class type. See (C++98 [5.2.3p2]).
- class CXXScalarValueInitExpr : public Expr {
- friend class ASTStmtReader;
- TypeSourceInfo *TypeInfo;
- public:
- /// Create an explicitly-written scalar-value initialization
- /// expression.
- CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo,
- SourceLocation RParenLoc)
- : Expr(CXXScalarValueInitExprClass, Type, VK_PRValue, OK_Ordinary),
- TypeInfo(TypeInfo) {
- CXXScalarValueInitExprBits.RParenLoc = RParenLoc;
- setDependence(computeDependence(this));
- }
- explicit CXXScalarValueInitExpr(EmptyShell Shell)
- : Expr(CXXScalarValueInitExprClass, Shell) {}
- TypeSourceInfo *getTypeSourceInfo() const {
- return TypeInfo;
- }
- SourceLocation getRParenLoc() const {
- return CXXScalarValueInitExprBits.RParenLoc;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY;
- SourceLocation getEndLoc() const { return getRParenLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXScalarValueInitExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Represents a new-expression for memory allocation and constructor
- /// calls, e.g: "new CXXNewExpr(foo)".
- class CXXNewExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXNewExpr, Stmt *, SourceRange> {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
- /// Points to the allocation function used.
- FunctionDecl *OperatorNew;
- /// Points to the deallocation function used in case of error. May be null.
- FunctionDecl *OperatorDelete;
- /// The allocated type-source information, as written in the source.
- TypeSourceInfo *AllocatedTypeInfo;
- /// Range of the entire new expression.
- SourceRange Range;
- /// Source-range of a paren-delimited initializer.
- SourceRange DirectInitRange;
- // CXXNewExpr is followed by several optional trailing objects.
- // They are in order:
- //
- // * An optional "Stmt *" for the array size expression.
- // Present if and ony if isArray().
- //
- // * An optional "Stmt *" for the init expression.
- // Present if and only if hasInitializer().
- //
- // * An array of getNumPlacementArgs() "Stmt *" for the placement new
- // arguments, if any.
- //
- // * An optional SourceRange for the range covering the parenthesized type-id
- // if the allocated type was expressed as a parenthesized type-id.
- // Present if and only if isParenTypeId().
- unsigned arraySizeOffset() const { return 0; }
- unsigned initExprOffset() const { return arraySizeOffset() + isArray(); }
- unsigned placementNewArgsOffset() const {
- return initExprOffset() + hasInitializer();
- }
- unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
- return isArray() + hasInitializer() + getNumPlacementArgs();
- }
- unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
- return isParenTypeId();
- }
- public:
- enum InitializationStyle {
- /// New-expression has no initializer as written.
- NoInit,
- /// New-expression has a C++98 paren-delimited initializer.
- CallInit,
- /// New-expression has a C++11 list-initializer.
- ListInit
- };
- private:
- /// Build a c++ new expression.
- CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
- FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
- bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Optional<Expr *> ArraySize,
- InitializationStyle InitializationStyle, Expr *Initializer,
- QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
- SourceRange DirectInitRange);
- /// Build an empty c++ new expression.
- CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs,
- bool IsParenTypeId);
- public:
- /// Create a c++ new expression.
- static CXXNewExpr *
- Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
- FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
- bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Optional<Expr *> ArraySize,
- InitializationStyle InitializationStyle, Expr *Initializer,
- QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
- SourceRange DirectInitRange);
- /// Create an empty c++ new expression.
- static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray,
- bool HasInit, unsigned NumPlacementArgs,
- bool IsParenTypeId);
- QualType getAllocatedType() const {
- return getType()->castAs<PointerType>()->getPointeeType();
- }
- TypeSourceInfo *getAllocatedTypeSourceInfo() const {
- return AllocatedTypeInfo;
- }
- /// True if the allocation result needs to be null-checked.
- ///
- /// C++11 [expr.new]p13:
- /// If the allocation function returns null, initialization shall
- /// not be done, the deallocation function shall not be called,
- /// and the value of the new-expression shall be null.
- ///
- /// C++ DR1748:
- /// If the allocation function is a reserved placement allocation
- /// function that returns null, the behavior is undefined.
- ///
- /// An allocation function is not allowed to return null unless it
- /// has a non-throwing exception-specification. The '03 rule is
- /// identical except that the definition of a non-throwing
- /// exception specification is just "is it throw()?".
- bool shouldNullCheckAllocation() const;
- FunctionDecl *getOperatorNew() const { return OperatorNew; }
- void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
- void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
- bool isArray() const { return CXXNewExprBits.IsArray; }
- Optional<Expr *> getArraySize() {
- if (!isArray())
- return None;
- return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
- }
- Optional<const Expr *> getArraySize() const {
- if (!isArray())
- return None;
- return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
- }
- unsigned getNumPlacementArgs() const {
- return CXXNewExprBits.NumPlacementArgs;
- }
- Expr **getPlacementArgs() {
- return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>() +
- placementNewArgsOffset());
- }
- Expr *getPlacementArg(unsigned I) {
- assert((I < getNumPlacementArgs()) && "Index out of range!");
- return getPlacementArgs()[I];
- }
- const Expr *getPlacementArg(unsigned I) const {
- return const_cast<CXXNewExpr *>(this)->getPlacementArg(I);
- }
- bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; }
- SourceRange getTypeIdParens() const {
- return isParenTypeId() ? getTrailingObjects<SourceRange>()[0]
- : SourceRange();
- }
- bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
- /// Whether this new-expression has any initializer at all.
- bool hasInitializer() const {
- return CXXNewExprBits.StoredInitializationStyle > 0;
- }
- /// The kind of initializer this new-expression has.
- InitializationStyle getInitializationStyle() const {
- if (CXXNewExprBits.StoredInitializationStyle == 0)
- return NoInit;
- return static_cast<InitializationStyle>(
- CXXNewExprBits.StoredInitializationStyle - 1);
- }
- /// The initializer of this new-expression.
- Expr *getInitializer() {
- return hasInitializer()
- ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
- : nullptr;
- }
- const Expr *getInitializer() const {
- return hasInitializer()
- ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()])
- : nullptr;
- }
- /// Returns the CXXConstructExpr from this new-expression, or null.
- const CXXConstructExpr *getConstructExpr() const {
- return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
- }
- /// Indicates whether the required alignment should be implicitly passed to
- /// the allocation function.
- bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; }
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter.
- bool doesUsualArrayDeleteWantSize() const {
- return CXXNewExprBits.UsualArrayDeleteWantsSize;
- }
- using arg_iterator = ExprIterator;
- using const_arg_iterator = ConstExprIterator;
- llvm::iterator_range<arg_iterator> placement_arguments() {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
- llvm::iterator_range<const_arg_iterator> placement_arguments() const {
- return llvm::make_range(placement_arg_begin(), placement_arg_end());
- }
- arg_iterator placement_arg_begin() {
- return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
- }
- arg_iterator placement_arg_end() {
- return placement_arg_begin() + getNumPlacementArgs();
- }
- const_arg_iterator placement_arg_begin() const {
- return getTrailingObjects<Stmt *>() + placementNewArgsOffset();
- }
- const_arg_iterator placement_arg_end() const {
- return placement_arg_begin() + getNumPlacementArgs();
- }
- using raw_arg_iterator = Stmt **;
- raw_arg_iterator raw_arg_begin() { return getTrailingObjects<Stmt *>(); }
- raw_arg_iterator raw_arg_end() {
- return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
- }
- const_arg_iterator raw_arg_begin() const {
- return getTrailingObjects<Stmt *>();
- }
- const_arg_iterator raw_arg_end() const {
- return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>());
- }
- SourceLocation getBeginLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
- SourceRange getDirectInitRange() const { return DirectInitRange; }
- SourceRange getSourceRange() const { return Range; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNewExprClass;
- }
- // Iterators
- child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); }
- const_child_range children() const {
- return const_child_range(const_cast<CXXNewExpr *>(this)->children());
- }
- };
- /// Represents a \c delete expression for memory deallocation and
- /// destructor calls, e.g. "delete[] pArray".
- class CXXDeleteExpr : public Expr {
- friend class ASTStmtReader;
- /// Points to the operator delete overload that is used. Could be a member.
- FunctionDecl *OperatorDelete = nullptr;
- /// The pointer expression to be deleted.
- Stmt *Argument = nullptr;
- public:
- CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm,
- bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize,
- FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc)
- : Expr(CXXDeleteExprClass, Ty, VK_PRValue, OK_Ordinary),
- OperatorDelete(OperatorDelete), Argument(Arg) {
- CXXDeleteExprBits.GlobalDelete = GlobalDelete;
- CXXDeleteExprBits.ArrayForm = ArrayForm;
- CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten;
- CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
- CXXDeleteExprBits.Loc = Loc;
- setDependence(computeDependence(this));
- }
- explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {}
- bool isGlobalDelete() const { return CXXDeleteExprBits.GlobalDelete; }
- bool isArrayForm() const { return CXXDeleteExprBits.ArrayForm; }
- bool isArrayFormAsWritten() const {
- return CXXDeleteExprBits.ArrayFormAsWritten;
- }
- /// Answers whether the usual array deallocation function for the
- /// allocated type expects the size of the allocation as a
- /// parameter. This can be true even if the actual deallocation
- /// function that we're using doesn't want a size.
- bool doesUsualArrayDeleteWantSize() const {
- return CXXDeleteExprBits.UsualArrayDeleteWantsSize;
- }
- FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
- Expr *getArgument() { return cast<Expr>(Argument); }
- const Expr *getArgument() const { return cast<Expr>(Argument); }
- /// Retrieve the type being destroyed.
- ///
- /// If the type being destroyed is a dependent type which may or may not
- /// be a pointer, return an invalid type.
- QualType getDestroyedType() const;
- SourceLocation getBeginLoc() const { return CXXDeleteExprBits.Loc; }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return Argument->getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDeleteExprClass;
- }
- // Iterators
- child_range children() { return child_range(&Argument, &Argument + 1); }
- const_child_range children() const {
- return const_child_range(&Argument, &Argument + 1);
- }
- };
- /// Stores the type being destroyed by a pseudo-destructor expression.
- class PseudoDestructorTypeStorage {
- /// Either the type source information or the name of the type, if
- /// it couldn't be resolved due to type-dependence.
- llvm::PointerUnion<TypeSourceInfo *, IdentifierInfo *> Type;
- /// The starting source location of the pseudo-destructor type.
- SourceLocation Location;
- public:
- PseudoDestructorTypeStorage() = default;
- PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc)
- : Type(II), Location(Loc) {}
- PseudoDestructorTypeStorage(TypeSourceInfo *Info);
- TypeSourceInfo *getTypeSourceInfo() const {
- return Type.dyn_cast<TypeSourceInfo *>();
- }
- IdentifierInfo *getIdentifier() const {
- return Type.dyn_cast<IdentifierInfo *>();
- }
- SourceLocation getLocation() const { return Location; }
- };
- /// Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
- ///
- /// A pseudo-destructor is an expression that looks like a member access to a
- /// destructor of a scalar type, except that scalar types don't have
- /// destructors. For example:
- ///
- /// \code
- /// typedef int T;
- /// void f(int *p) {
- /// p->T::~T();
- /// }
- /// \endcode
- ///
- /// Pseudo-destructors typically occur when instantiating templates such as:
- ///
- /// \code
- /// template<typename T>
- /// void destroy(T* ptr) {
- /// ptr->T::~T();
- /// }
- /// \endcode
- ///
- /// for scalar types. A pseudo-destructor expression has no run-time semantics
- /// beyond evaluating the base expression.
- class CXXPseudoDestructorExpr : public Expr {
- friend class ASTStmtReader;
- /// The base expression (that is being destroyed).
- Stmt *Base = nullptr;
- /// Whether the operator was an arrow ('->'); otherwise, it was a
- /// period ('.').
- bool IsArrow : 1;
- /// The location of the '.' or '->' operator.
- SourceLocation OperatorLoc;
- /// The nested-name-specifier that follows the operator, if present.
- NestedNameSpecifierLoc QualifierLoc;
- /// The type that precedes the '::' in a qualified pseudo-destructor
- /// expression.
- TypeSourceInfo *ScopeType = nullptr;
- /// The location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation ColonColonLoc;
- /// The location of the '~'.
- SourceLocation TildeLoc;
- /// The type being destroyed, or its name if we were unable to
- /// resolve the name.
- PseudoDestructorTypeStorage DestroyedType;
- public:
- CXXPseudoDestructorExpr(const ASTContext &Context,
- Expr *Base, bool isArrow, SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- TypeSourceInfo *ScopeType,
- SourceLocation ColonColonLoc,
- SourceLocation TildeLoc,
- PseudoDestructorTypeStorage DestroyedType);
- explicit CXXPseudoDestructorExpr(EmptyShell Shell)
- : Expr(CXXPseudoDestructorExprClass, Shell), IsArrow(false) {}
- Expr *getBase() const { return cast<Expr>(Base); }
- /// Determines whether this member expression actually had
- /// a C++ nested-name-specifier prior to the name of the member, e.g.,
- /// x->Base::foo.
- bool hasQualifier() const { return QualifierLoc.hasQualifier(); }
- /// Retrieves the nested-name-specifier that qualifies the type name,
- /// with source-location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// If the member name was qualified, retrieves the
- /// nested-name-specifier that precedes the member name. Otherwise, returns
- /// null.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
- /// Determine whether this pseudo-destructor expression was written
- /// using an '->' (otherwise, it used a '.').
- bool isArrow() const { return IsArrow; }
- /// Retrieve the location of the '.' or '->' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// Retrieve the scope type in a qualified pseudo-destructor
- /// expression.
- ///
- /// Pseudo-destructor expressions can have extra qualification within them
- /// that is not part of the nested-name-specifier, e.g., \c p->T::~T().
- /// Here, if the object type of the expression is (or may be) a scalar type,
- /// \p T may also be a scalar type and, therefore, cannot be part of a
- /// nested-name-specifier. It is stored as the "scope type" of the pseudo-
- /// destructor expression.
- TypeSourceInfo *getScopeTypeInfo() const { return ScopeType; }
- /// Retrieve the location of the '::' in a qualified pseudo-destructor
- /// expression.
- SourceLocation getColonColonLoc() const { return ColonColonLoc; }
- /// Retrieve the location of the '~'.
- SourceLocation getTildeLoc() const { return TildeLoc; }
- /// Retrieve the source location information for the type
- /// being destroyed.
- ///
- /// This type-source information is available for non-dependent
- /// pseudo-destructor expressions and some dependent pseudo-destructor
- /// expressions. Returns null if we only have the identifier for a
- /// dependent pseudo-destructor expression.
- TypeSourceInfo *getDestroyedTypeInfo() const {
- return DestroyedType.getTypeSourceInfo();
- }
- /// In a dependent pseudo-destructor expression for which we do not
- /// have full type information on the destroyed type, provides the name
- /// of the destroyed type.
- IdentifierInfo *getDestroyedTypeIdentifier() const {
- return DestroyedType.getIdentifier();
- }
- /// Retrieve the type being destroyed.
- QualType getDestroyedType() const;
- /// Retrieve the starting location of the type being destroyed.
- SourceLocation getDestroyedTypeLoc() const {
- return DestroyedType.getLocation();
- }
- /// Set the name of destroyed type for a dependent pseudo-destructor
- /// expression.
- void setDestroyedType(IdentifierInfo *II, SourceLocation Loc) {
- DestroyedType = PseudoDestructorTypeStorage(II, Loc);
- }
- /// Set the destroyed type.
- void setDestroyedType(TypeSourceInfo *Info) {
- DestroyedType = PseudoDestructorTypeStorage(Info);
- }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return Base->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY;
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXPseudoDestructorExprClass;
- }
- // Iterators
- child_range children() { return child_range(&Base, &Base + 1); }
- const_child_range children() const {
- return const_child_range(&Base, &Base + 1);
- }
- };
- /// A type trait used in the implementation of various C++11 and
- /// Library TR1 trait templates.
- ///
- /// \code
- /// __is_pod(int) == true
- /// __is_enum(std::string) == false
- /// __is_trivially_constructible(vector<int>, int*, int*)
- /// \endcode
- class TypeTraitExpr final
- : public Expr,
- private llvm::TrailingObjects<TypeTraitExpr, TypeSourceInfo *> {
- /// The location of the type trait keyword.
- SourceLocation Loc;
- /// The location of the closing parenthesis.
- SourceLocation RParenLoc;
- // Note: The TypeSourceInfos for the arguments are allocated after the
- // TypeTraitExpr.
- TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
- TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {}
- size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
- return getNumArgs();
- }
- public:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
- /// Create a new type trait expression.
- static TypeTraitExpr *Create(const ASTContext &C, QualType T,
- SourceLocation Loc, TypeTrait Kind,
- ArrayRef<TypeSourceInfo *> Args,
- SourceLocation RParenLoc,
- bool Value);
- static TypeTraitExpr *CreateDeserialized(const ASTContext &C,
- unsigned NumArgs);
- /// Determine which type trait this expression uses.
- TypeTrait getTrait() const {
- return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
- }
- bool getValue() const {
- assert(!isValueDependent());
- return TypeTraitExprBits.Value;
- }
- /// Determine the number of arguments to this type trait.
- unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
- /// Retrieve the Ith argument.
- TypeSourceInfo *getArg(unsigned I) const {
- assert(I < getNumArgs() && "Argument out-of-range");
- return getArgs()[I];
- }
- /// Retrieve the argument types.
- ArrayRef<TypeSourceInfo *> getArgs() const {
- return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
- getNumArgs());
- }
- SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == TypeTraitExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// An Embarcadero array type trait, as used in the implementation of
- /// __array_rank and __array_extent.
- ///
- /// Example:
- /// \code
- /// __array_rank(int[10][20]) == 2
- /// __array_extent(int, 1) == 20
- /// \endcode
- class ArrayTypeTraitExpr : public Expr {
- /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
- unsigned ATT : 2;
- /// The value of the type trait. Unspecified if dependent.
- uint64_t Value = 0;
- /// The array dimension being queried, or -1 if not used.
- Expr *Dimension;
- /// The location of the type trait keyword.
- SourceLocation Loc;
- /// The location of the closing paren.
- SourceLocation RParen;
- /// The type being queried.
- TypeSourceInfo *QueriedType = nullptr;
- public:
- friend class ASTStmtReader;
- ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
- TypeSourceInfo *queried, uint64_t value, Expr *dimension,
- SourceLocation rparen, QualType ty)
- : Expr(ArrayTypeTraitExprClass, ty, VK_PRValue, OK_Ordinary), ATT(att),
- Value(value), Dimension(dimension), Loc(loc), RParen(rparen),
- QueriedType(queried) {
- assert(att <= ATT_Last && "invalid enum value!");
- assert(static_cast<unsigned>(att) == ATT && "ATT overflow!");
- setDependence(computeDependence(this));
- }
- explicit ArrayTypeTraitExpr(EmptyShell Empty)
- : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {}
- SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
- ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
- QualType getQueriedType() const { return QueriedType->getType(); }
- TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
- uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
- Expr *getDimensionExpression() const { return Dimension; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ArrayTypeTraitExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// An expression trait intrinsic.
- ///
- /// Example:
- /// \code
- /// __is_lvalue_expr(std::cout) == true
- /// __is_lvalue_expr(1) == false
- /// \endcode
- class ExpressionTraitExpr : public Expr {
- /// The trait. A ExpressionTrait enum in MSVC compatible unsigned.
- unsigned ET : 31;
- /// The value of the type trait. Unspecified if dependent.
- unsigned Value : 1;
- /// The location of the type trait keyword.
- SourceLocation Loc;
- /// The location of the closing paren.
- SourceLocation RParen;
- /// The expression being queried.
- Expr* QueriedExpression = nullptr;
- public:
- friend class ASTStmtReader;
- ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried,
- bool value, SourceLocation rparen, QualType resultType)
- : Expr(ExpressionTraitExprClass, resultType, VK_PRValue, OK_Ordinary),
- ET(et), Value(value), Loc(loc), RParen(rparen),
- QueriedExpression(queried) {
- assert(et <= ET_Last && "invalid enum value!");
- assert(static_cast<unsigned>(et) == ET && "ET overflow!");
- setDependence(computeDependence(this));
- }
- explicit ExpressionTraitExpr(EmptyShell Empty)
- : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {}
- SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParen; }
- ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
- Expr *getQueriedExpression() const { return QueriedExpression; }
- bool getValue() const { return Value; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExpressionTraitExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// A reference to an overloaded function set, either an
- /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr.
- class OverloadExpr : public Expr {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- /// The common name of these declarations.
- DeclarationNameInfo NameInfo;
- /// The nested-name-specifier that qualifies the name, if any.
- NestedNameSpecifierLoc QualifierLoc;
- protected:
- OverloadExpr(StmtClass SC, const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End,
- bool KnownDependent, bool KnownInstantiationDependent,
- bool KnownContainsUnexpandedParameterPack);
- OverloadExpr(StmtClass SC, EmptyShell Empty, unsigned NumResults,
- bool HasTemplateKWAndArgsInfo);
- /// Return the results. Defined after UnresolvedMemberExpr.
- inline DeclAccessPair *getTrailingResults();
- const DeclAccessPair *getTrailingResults() const {
- return const_cast<OverloadExpr *>(this)->getTrailingResults();
- }
- /// Return the optional template keyword and arguments info.
- /// Defined after UnresolvedMemberExpr.
- inline ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo();
- const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const {
- return const_cast<OverloadExpr *>(this)
- ->getTrailingASTTemplateKWAndArgsInfo();
- }
- /// Return the optional template arguments. Defined after
- /// UnresolvedMemberExpr.
- inline TemplateArgumentLoc *getTrailingTemplateArgumentLoc();
- const TemplateArgumentLoc *getTrailingTemplateArgumentLoc() const {
- return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
- }
- bool hasTemplateKWAndArgsInfo() const {
- return OverloadExprBits.HasTemplateKWAndArgsInfo;
- }
- public:
- struct FindResult {
- OverloadExpr *Expression;
- bool IsAddressOfOperand;
- bool HasFormOfMemberPointer;
- };
- /// Finds the overloaded expression in the given expression \p E of
- /// OverloadTy.
- ///
- /// \return the expression (which must be there) and true if it has
- /// the particular form of a member pointer expression
- static FindResult find(Expr *E) {
- assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload));
- FindResult Result;
- E = E->IgnoreParens();
- if (isa<UnaryOperator>(E)) {
- assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf);
- E = cast<UnaryOperator>(E)->getSubExpr();
- auto *Ovl = cast<OverloadExpr>(E->IgnoreParens());
- Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier());
- Result.IsAddressOfOperand = true;
- Result.Expression = Ovl;
- } else {
- Result.HasFormOfMemberPointer = false;
- Result.IsAddressOfOperand = false;
- Result.Expression = cast<OverloadExpr>(E);
- }
- return Result;
- }
- /// Gets the naming class of this lookup, if any.
- /// Defined after UnresolvedMemberExpr.
- inline CXXRecordDecl *getNamingClass();
- const CXXRecordDecl *getNamingClass() const {
- return const_cast<OverloadExpr *>(this)->getNamingClass();
- }
- using decls_iterator = UnresolvedSetImpl::iterator;
- decls_iterator decls_begin() const {
- return UnresolvedSetIterator(getTrailingResults());
- }
- decls_iterator decls_end() const {
- return UnresolvedSetIterator(getTrailingResults() + getNumDecls());
- }
- llvm::iterator_range<decls_iterator> decls() const {
- return llvm::make_range(decls_begin(), decls_end());
- }
- /// Gets the number of declarations in the unresolved set.
- unsigned getNumDecls() const { return OverloadExprBits.NumResults; }
- /// Gets the full name info.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- /// Gets the name looked up.
- DeclarationName getName() const { return NameInfo.getName(); }
- /// Gets the location of the name.
- SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
- /// Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
- /// Fetches the nested-name qualifier with source-location
- /// information, if one was given.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// Retrieve the location of the template keyword preceding
- /// this name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc;
- }
- /// Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the name, if any.
- SourceLocation getLAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc;
- }
- /// Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc;
- }
- /// Determines whether the name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
- /// Determines whether this expression had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
- return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc();
- }
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
- return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs;
- }
- ArrayRef<TemplateArgumentLoc> template_arguments() const {
- return {getTemplateArgs(), getNumTemplateArgs()};
- }
- /// Copies the template arguments into the given structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass ||
- T->getStmtClass() == UnresolvedMemberExprClass;
- }
- };
- /// A reference to a name which we were able to look up during
- /// parsing but could not resolve to a specific declaration.
- ///
- /// This arises in several ways:
- /// * we might be waiting for argument-dependent lookup;
- /// * the name might resolve to an overloaded function;
- /// and eventually:
- /// * the lookup might have included a function template.
- ///
- /// These never include UnresolvedUsingValueDecls, which are always class
- /// members and therefore appear only in UnresolvedMemberLookupExprs.
- class UnresolvedLookupExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<UnresolvedLookupExpr, DeclAccessPair,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- friend class ASTStmtReader;
- friend class OverloadExpr;
- friend TrailingObjects;
- /// The naming class (C++ [class.access.base]p5) of the lookup, if
- /// any. This can generally be recalculated from the context chain,
- /// but that can be fairly expensive for unqualified lookups.
- CXXRecordDecl *NamingClass;
- // UnresolvedLookupExpr is followed by several trailing objects.
- // They are in order:
- //
- // * An array of getNumResults() DeclAccessPair for the results. These are
- // undesugared, which is to say, they may include UsingShadowDecls.
- // Access is relative to the naming class.
- //
- // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
- // template keyword and arguments. Present if and only if
- // hasTemplateKWAndArgsInfo().
- //
- // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
- // location information for the explicitly specified template arguments.
- UnresolvedLookupExpr(const ASTContext &Context, CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo, bool RequiresADL,
- bool Overloaded,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
- bool HasTemplateKWAndArgsInfo);
- unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
- return getNumDecls();
- }
- unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo();
- }
- public:
- static UnresolvedLookupExpr *
- Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc,
- const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- static UnresolvedLookupExpr *
- Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
- NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo, bool RequiresADL,
- const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
- static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumResults,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
- /// True if this declaration should be extended by
- /// argument-dependent lookup.
- bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; }
- /// True if this lookup is overloaded.
- bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; }
- /// Gets the 'naming class' (in the sense of C++0x
- /// [class.access.base]p5) of the lookup. This is the scope
- /// that was looked in to find these results.
- CXXRecordDecl *getNamingClass() { return NamingClass; }
- const CXXRecordDecl *getNamingClass() const { return NamingClass; }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getNameInfo().getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getNameInfo().getEndLoc();
- }
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedLookupExprClass;
- }
- };
- /// A qualified reference to a name whose declaration cannot
- /// yet be resolved.
- ///
- /// DependentScopeDeclRefExpr is similar to DeclRefExpr in that
- /// it expresses a reference to a declaration such as
- /// X<T>::value. The difference, however, is that an
- /// DependentScopeDeclRefExpr node is used only within C++ templates when
- /// the qualification (e.g., X<T>::) refers to a dependent type. In
- /// this case, X<T>::value cannot resolve to a declaration because the
- /// declaration will differ from one instantiation of X<T> to the
- /// next. Therefore, DependentScopeDeclRefExpr keeps track of the
- /// qualifier (X<T>::) and the name of the entity being referenced
- /// ("value"). Such expressions will instantiate to a DeclRefExpr once the
- /// declaration can be found.
- class DependentScopeDeclRefExpr final
- : public Expr,
- private llvm::TrailingObjects<DependentScopeDeclRefExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
- /// The nested-name-specifier that qualifies this unresolved
- /// declaration name.
- NestedNameSpecifierLoc QualifierLoc;
- /// The name of the entity we will be referencing.
- DeclarationNameInfo NameInfo;
- DependentScopeDeclRefExpr(QualType Ty, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *Args);
- size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo();
- }
- bool hasTemplateKWAndArgsInfo() const {
- return DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo;
- }
- public:
- static DependentScopeDeclRefExpr *
- Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
- static DependentScopeDeclRefExpr *CreateEmpty(const ASTContext &Context,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
- /// Retrieve the name that this expression refers to.
- const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
- /// Retrieve the name that this expression refers to.
- DeclarationName getDeclName() const { return NameInfo.getName(); }
- /// Retrieve the location of the name within the expression.
- ///
- /// For example, in "X<T>::value" this is the location of "value".
- SourceLocation getLocation() const { return NameInfo.getLoc(); }
- /// Retrieve the nested-name-specifier that qualifies the
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// Retrieve the nested-name-specifier that qualifies this
- /// declaration.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
- /// Retrieve the location of the template keyword preceding
- /// this name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
- /// Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the name, if any.
- SourceLocation getLAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
- /// Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the name, if any.
- SourceLocation getRAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
- /// Determines whether the name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
- /// Determines whether this lookup had explicit template arguments.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
- /// Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
- TemplateArgumentLoc const *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
- return getTrailingObjects<TemplateArgumentLoc>();
- }
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
- ArrayRef<TemplateArgumentLoc> template_arguments() const {
- return {getTemplateArgs(), getNumTemplateArgs()};
- }
- /// Note: getBeginLoc() is the start of the whole DependentScopeDeclRefExpr,
- /// and differs from getLocation().getStart().
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return QualifierLoc.getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getLocation();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DependentScopeDeclRefExprClass;
- }
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Represents an expression -- generally a full-expression -- that
- /// introduces cleanups to be run at the end of the sub-expression's
- /// evaluation. The most common source of expression-introduced
- /// cleanups is temporary objects in C++, but several other kinds of
- /// expressions can create cleanups, including basically every
- /// call in ARC that returns an Objective-C pointer.
- ///
- /// This expression also tracks whether the sub-expression contains a
- /// potentially-evaluated block literal. The lifetime of a block
- /// literal is the extent of the enclosing scope.
- class ExprWithCleanups final
- : public FullExpr,
- private llvm::TrailingObjects<
- ExprWithCleanups,
- llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> {
- public:
- /// The type of objects that are kept in the cleanup.
- /// It's useful to remember the set of blocks and block-scoped compound
- /// literals; we could also remember the set of temporaries, but there's
- /// currently no need.
- using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>;
- private:
- friend class ASTStmtReader;
- friend TrailingObjects;
- ExprWithCleanups(EmptyShell, unsigned NumObjects);
- ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
- ArrayRef<CleanupObject> Objects);
- public:
- static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty,
- unsigned numObjects);
- static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr,
- bool CleanupsHaveSideEffects,
- ArrayRef<CleanupObject> objects);
- ArrayRef<CleanupObject> getObjects() const {
- return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(),
- getNumObjects());
- }
- unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
- CleanupObject getObject(unsigned i) const {
- assert(i < getNumObjects() && "Index out of range");
- return getObjects()[i];
- }
- bool cleanupsHaveSideEffects() const {
- return ExprWithCleanupsBits.CleanupsHaveSideEffects;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return SubExpr->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return SubExpr->getEndLoc();
- }
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ExprWithCleanupsClass;
- }
- // Iterators
- child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
- const_child_range children() const {
- return const_child_range(&SubExpr, &SubExpr + 1);
- }
- };
- /// Describes an explicit type conversion that uses functional
- /// notion but could not be resolved because one or more arguments are
- /// type-dependent.
- ///
- /// The explicit type conversions expressed by
- /// CXXUnresolvedConstructExpr have the form <tt>T(a1, a2, ..., aN)</tt>,
- /// where \c T is some type and \c a1, \c a2, ..., \c aN are values, and
- /// either \c T is a dependent type or one or more of the <tt>a</tt>'s is
- /// type-dependent. For example, this would occur in a template such
- /// as:
- ///
- /// \code
- /// template<typename T, typename A1>
- /// inline T make_a(const A1& a1) {
- /// return T(a1);
- /// }
- /// \endcode
- ///
- /// When the returned expression is instantiated, it may resolve to a
- /// constructor call, conversion function call, or some kind of type
- /// conversion.
- class CXXUnresolvedConstructExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> {
- friend class ASTStmtReader;
- friend TrailingObjects;
- /// The type being constructed.
- TypeSourceInfo *TSI;
- /// The location of the left parentheses ('(').
- SourceLocation LParenLoc;
- /// The location of the right parentheses (')').
- SourceLocation RParenLoc;
- CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI,
- SourceLocation LParenLoc, ArrayRef<Expr *> Args,
- SourceLocation RParenLoc);
- CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) {
- CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
- }
- public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
- QualType T, TypeSourceInfo *TSI,
- SourceLocation LParenLoc,
- ArrayRef<Expr *> Args,
- SourceLocation RParenLoc);
- static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumArgs);
- /// Retrieve the type that is being constructed, as specified
- /// in the source code.
- QualType getTypeAsWritten() const { return TSI->getType(); }
- /// Retrieve the type source information for the type being
- /// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
- /// Retrieve the location of the left parentheses ('(') that
- /// precedes the argument list.
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- /// Retrieve the location of the right parentheses (')') that
- /// follows the argument list.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- /// Determine whether this expression models list-initialization.
- /// If so, there will be exactly one subexpression, which will be
- /// an InitListExpr.
- bool isListInitialization() const { return LParenLoc.isInvalid(); }
- /// Retrieve the number of arguments.
- unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; }
- using arg_iterator = Expr **;
- using arg_range = llvm::iterator_range<arg_iterator>;
- arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
- arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
- arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
- using const_arg_iterator = const Expr* const *;
- using const_arg_range = llvm::iterator_range<const_arg_iterator>;
- const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
- const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
- const_arg_range arguments() const {
- return const_arg_range(arg_begin(), arg_end());
- }
- Expr *getArg(unsigned I) {
- assert(I < getNumArgs() && "Argument index out-of-range");
- return arg_begin()[I];
- }
- const Expr *getArg(unsigned I) const {
- assert(I < getNumArgs() && "Argument index out-of-range");
- return arg_begin()[I];
- }
- void setArg(unsigned I, Expr *E) {
- assert(I < getNumArgs() && "Argument index out-of-range");
- arg_begin()[I] = E;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY;
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (!RParenLoc.isValid() && getNumArgs() > 0)
- return getArg(getNumArgs() - 1)->getEndLoc();
- return RParenLoc;
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXUnresolvedConstructExprClass;
- }
- // Iterators
- child_range children() {
- auto **begin = reinterpret_cast<Stmt **>(arg_begin());
- return child_range(begin, begin + getNumArgs());
- }
- const_child_range children() const {
- auto **begin = reinterpret_cast<Stmt **>(
- const_cast<CXXUnresolvedConstructExpr *>(this)->arg_begin());
- return const_child_range(begin, begin + getNumArgs());
- }
- };
- /// Represents a C++ member access expression where the actual
- /// member referenced could not be resolved because the base
- /// expression or the member name was dependent.
- ///
- /// Like UnresolvedMemberExprs, these can be either implicit or
- /// explicit accesses. It is only possible to get one of these with
- /// an implicit access if a qualifier is provided.
- class CXXDependentScopeMemberExpr final
- : public Expr,
- private llvm::TrailingObjects<CXXDependentScopeMemberExpr,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc, NamedDecl *> {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
- /// The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f. Can be null in implicit accesses.
- Stmt *Base;
- /// The type of the base expression. Never null, even for
- /// implicit accesses.
- QualType BaseType;
- /// The nested-name-specifier that precedes the member name, if any.
- /// FIXME: This could be in principle store as a trailing object.
- /// However the performance impact of doing so should be investigated first.
- NestedNameSpecifierLoc QualifierLoc;
- /// The member to which this member expression refers, which
- /// can be name, overloaded operator, or destructor.
- ///
- /// FIXME: could also be a template-id
- DeclarationNameInfo MemberNameInfo;
- // CXXDependentScopeMemberExpr is followed by several trailing objects,
- // some of which optional. They are in order:
- //
- // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
- // template keyword and arguments. Present if and only if
- // hasTemplateKWAndArgsInfo().
- //
- // * An array of getNumTemplateArgs() TemplateArgumentLoc containing location
- // information for the explicitly specified template arguments.
- //
- // * An optional NamedDecl *. In a qualified member access expression such
- // as t->Base::f, this member stores the resolves of name lookup in the
- // context of the member access expression, to be used at instantiation
- // time. Present if and only if hasFirstQualifierFoundInScope().
- bool hasTemplateKWAndArgsInfo() const {
- return CXXDependentScopeMemberExprBits.HasTemplateKWAndArgsInfo;
- }
- bool hasFirstQualifierFoundInScope() const {
- return CXXDependentScopeMemberExprBits.HasFirstQualifierFoundInScope;
- }
- unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo();
- }
- unsigned numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
- return getNumTemplateArgs();
- }
- unsigned numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return hasFirstQualifierFoundInScope();
- }
- CXXDependentScopeMemberExpr(const ASTContext &Ctx, Expr *Base,
- QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
- CXXDependentScopeMemberExpr(EmptyShell Empty, bool HasTemplateKWAndArgsInfo,
- bool HasFirstQualifierFoundInScope);
- public:
- static CXXDependentScopeMemberExpr *
- Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope,
- DeclarationNameInfo MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs);
- static CXXDependentScopeMemberExpr *
- CreateEmpty(const ASTContext &Ctx, bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs, bool HasFirstQualifierFoundInScope);
- /// True if this is an implicit access, i.e. one in which the
- /// member being accessed was not written in the source. The source
- /// location of the operator is invalid in this case.
- bool isImplicitAccess() const {
- if (!Base)
- return true;
- return cast<Expr>(Base)->isImplicitCXXThis();
- }
- /// Retrieve the base object of this member expressions,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
- QualType getBaseType() const { return BaseType; }
- /// Determine whether this member expression used the '->'
- /// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return CXXDependentScopeMemberExprBits.IsArrow; }
- /// Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const {
- return CXXDependentScopeMemberExprBits.OperatorLoc;
- }
- /// Retrieve the nested-name-specifier that qualifies the member name.
- NestedNameSpecifier *getQualifier() const {
- return QualifierLoc.getNestedNameSpecifier();
- }
- /// Retrieve the nested-name-specifier that qualifies the member
- /// name, with source location information.
- NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
- /// Retrieve the first part of the nested-name-specifier that was
- /// found in the scope of the member access expression when the member access
- /// was initially parsed.
- ///
- /// This function only returns a useful result when member access expression
- /// uses a qualified member name, e.g., "x.Base::f". Here, the declaration
- /// returned by this function describes what was found by unqualified name
- /// lookup for the identifier "Base" within the scope of the member access
- /// expression itself. At template instantiation time, this information is
- /// combined with the results of name lookup into the type of the object
- /// expression itself (the class type of x).
- NamedDecl *getFirstQualifierFoundInScope() const {
- if (!hasFirstQualifierFoundInScope())
- return nullptr;
- return *getTrailingObjects<NamedDecl *>();
- }
- /// Retrieve the name of the member that this expression refers to.
- const DeclarationNameInfo &getMemberNameInfo() const {
- return MemberNameInfo;
- }
- /// Retrieve the name of the member that this expression refers to.
- DeclarationName getMember() const { return MemberNameInfo.getName(); }
- // Retrieve the location of the name of the member that this
- // expression refers to.
- SourceLocation getMemberLoc() const { return MemberNameInfo.getLoc(); }
- /// Retrieve the location of the template keyword preceding the
- /// member name, if any.
- SourceLocation getTemplateKeywordLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc;
- }
- /// Retrieve the location of the left angle bracket starting the
- /// explicit template argument list following the member name, if any.
- SourceLocation getLAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc;
- }
- /// Retrieve the location of the right angle bracket ending the
- /// explicit template argument list following the member name, if any.
- SourceLocation getRAngleLoc() const {
- if (!hasTemplateKWAndArgsInfo())
- return SourceLocation();
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc;
- }
- /// Determines whether the member name was preceded by the template keyword.
- bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
- /// Determines whether this member expression actually had a C++
- /// template argument list explicitly specified, e.g., x.f<int>.
- bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); }
- /// Copies the template arguments (if present) into the given
- /// structure.
- void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const {
- if (hasExplicitTemplateArgs())
- getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto(
- getTrailingObjects<TemplateArgumentLoc>(), List);
- }
- /// Retrieve the template arguments provided as part of this
- /// template-id.
- const TemplateArgumentLoc *getTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return nullptr;
- return getTrailingObjects<TemplateArgumentLoc>();
- }
- /// Retrieve the number of template arguments provided as part of this
- /// template-id.
- unsigned getNumTemplateArgs() const {
- if (!hasExplicitTemplateArgs())
- return 0;
- return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs;
- }
- ArrayRef<TemplateArgumentLoc> template_arguments() const {
- return {getTemplateArgs(), getNumTemplateArgs()};
- }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getBeginLoc();
- if (getQualifier())
- return getQualifierLoc().getBeginLoc();
- return MemberNameInfo.getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return MemberNameInfo.getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXDependentScopeMemberExprClass;
- }
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
- const_child_range children() const {
- if (isImplicitAccess())
- return const_child_range(const_child_iterator(), const_child_iterator());
- return const_child_range(&Base, &Base + 1);
- }
- };
- /// Represents a C++ member access expression for which lookup
- /// produced a set of overloaded functions.
- ///
- /// The member access may be explicit or implicit:
- /// \code
- /// struct A {
- /// int a, b;
- /// int explicitAccess() { return this->a + this->A::b; }
- /// int implicitAccess() { return a + A::b; }
- /// };
- /// \endcode
- ///
- /// In the final AST, an explicit access always becomes a MemberExpr.
- /// An implicit access may become either a MemberExpr or a
- /// DeclRefExpr, depending on whether the member is static.
- class UnresolvedMemberExpr final
- : public OverloadExpr,
- private llvm::TrailingObjects<UnresolvedMemberExpr, DeclAccessPair,
- ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc> {
- friend class ASTStmtReader;
- friend class OverloadExpr;
- friend TrailingObjects;
- /// The expression for the base pointer or class reference,
- /// e.g., the \c x in x.f.
- ///
- /// This can be null if this is an 'unbased' member expression.
- Stmt *Base;
- /// The type of the base expression; never null.
- QualType BaseType;
- /// The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
- // UnresolvedMemberExpr is followed by several trailing objects.
- // They are in order:
- //
- // * An array of getNumResults() DeclAccessPair for the results. These are
- // undesugared, which is to say, they may include UsingShadowDecls.
- // Access is relative to the naming class.
- //
- // * An optional ASTTemplateKWAndArgsInfo for the explicitly specified
- // template keyword and arguments. Present if and only if
- // hasTemplateKWAndArgsInfo().
- //
- // * An array of getNumTemplateArgs() TemplateArgumentLoc containing
- // location information for the explicitly specified template arguments.
- UnresolvedMemberExpr(const ASTContext &Context, bool HasUnresolvedUsing,
- Expr *Base, QualType BaseType, bool IsArrow,
- SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- UnresolvedMemberExpr(EmptyShell Empty, unsigned NumResults,
- bool HasTemplateKWAndArgsInfo);
- unsigned numTrailingObjects(OverloadToken<DeclAccessPair>) const {
- return getNumDecls();
- }
- unsigned numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const {
- return hasTemplateKWAndArgsInfo();
- }
- public:
- static UnresolvedMemberExpr *
- Create(const ASTContext &Context, bool HasUnresolvedUsing, Expr *Base,
- QualType BaseType, bool IsArrow, SourceLocation OperatorLoc,
- NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &MemberNameInfo,
- const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
- static UnresolvedMemberExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumResults,
- bool HasTemplateKWAndArgsInfo,
- unsigned NumTemplateArgs);
- /// True if this is an implicit access, i.e., one in which the
- /// member being accessed was not written in the source.
- ///
- /// The source location of the operator is invalid in this case.
- bool isImplicitAccess() const;
- /// Retrieve the base object of this member expressions,
- /// e.g., the \c x in \c x.m.
- Expr *getBase() {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
- const Expr *getBase() const {
- assert(!isImplicitAccess());
- return cast<Expr>(Base);
- }
- QualType getBaseType() const { return BaseType; }
- /// Determine whether the lookup results contain an unresolved using
- /// declaration.
- bool hasUnresolvedUsing() const {
- return UnresolvedMemberExprBits.HasUnresolvedUsing;
- }
- /// Determine whether this member expression used the '->'
- /// operator; otherwise, it used the '.' operator.
- bool isArrow() const { return UnresolvedMemberExprBits.IsArrow; }
- /// Retrieve the location of the '->' or '.' operator.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// Retrieve the naming class of this lookup.
- CXXRecordDecl *getNamingClass();
- const CXXRecordDecl *getNamingClass() const {
- return const_cast<UnresolvedMemberExpr *>(this)->getNamingClass();
- }
- /// Retrieve the full name info for the member that this expression
- /// refers to.
- const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); }
- /// Retrieve the name of the member that this expression refers to.
- DeclarationName getMemberName() const { return getName(); }
- /// Retrieve the location of the name of the member that this
- /// expression refers to.
- SourceLocation getMemberLoc() const { return getNameLoc(); }
- /// Return the preferred location (the member name) for the arrow when
- /// diagnosing a problem with this expression.
- SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- if (!isImplicitAccess())
- return Base->getBeginLoc();
- if (NestedNameSpecifierLoc l = getQualifierLoc())
- return l.getBeginLoc();
- return getMemberNameInfo().getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (hasExplicitTemplateArgs())
- return getRAngleLoc();
- return getMemberNameInfo().getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnresolvedMemberExprClass;
- }
- // Iterators
- child_range children() {
- if (isImplicitAccess())
- return child_range(child_iterator(), child_iterator());
- return child_range(&Base, &Base + 1);
- }
- const_child_range children() const {
- if (isImplicitAccess())
- return const_child_range(const_child_iterator(), const_child_iterator());
- return const_child_range(&Base, &Base + 1);
- }
- };
- DeclAccessPair *OverloadExpr::getTrailingResults() {
- if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
- return ULE->getTrailingObjects<DeclAccessPair>();
- return cast<UnresolvedMemberExpr>(this)->getTrailingObjects<DeclAccessPair>();
- }
- ASTTemplateKWAndArgsInfo *OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() {
- if (!hasTemplateKWAndArgsInfo())
- return nullptr;
- if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
- return ULE->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- }
- TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() {
- if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
- return ULE->getTrailingObjects<TemplateArgumentLoc>();
- return cast<UnresolvedMemberExpr>(this)
- ->getTrailingObjects<TemplateArgumentLoc>();
- }
- CXXRecordDecl *OverloadExpr::getNamingClass() {
- if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(this))
- return ULE->getNamingClass();
- return cast<UnresolvedMemberExpr>(this)->getNamingClass();
- }
- /// Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
- ///
- /// The noexcept expression tests whether a given expression might throw. Its
- /// result is a boolean constant.
- class CXXNoexceptExpr : public Expr {
- friend class ASTStmtReader;
- Stmt *Operand;
- SourceRange Range;
- public:
- CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val,
- SourceLocation Keyword, SourceLocation RParen)
- : Expr(CXXNoexceptExprClass, Ty, VK_PRValue, OK_Ordinary),
- Operand(Operand), Range(Keyword, RParen) {
- CXXNoexceptExprBits.Value = Val == CT_Cannot;
- setDependence(computeDependence(this, Val));
- }
- CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {}
- Expr *getOperand() const { return static_cast<Expr *>(Operand); }
- SourceLocation getBeginLoc() const { return Range.getBegin(); }
- SourceLocation getEndLoc() const { return Range.getEnd(); }
- SourceRange getSourceRange() const { return Range; }
- bool getValue() const { return CXXNoexceptExprBits.Value; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXNoexceptExprClass;
- }
- // Iterators
- child_range children() { return child_range(&Operand, &Operand + 1); }
- const_child_range children() const {
- return const_child_range(&Operand, &Operand + 1);
- }
- };
- /// Represents a C++11 pack expansion that produces a sequence of
- /// expressions.
- ///
- /// A pack expansion expression contains a pattern (which itself is an
- /// expression) followed by an ellipsis. For example:
- ///
- /// \code
- /// template<typename F, typename ...Types>
- /// void forward(F f, Types &&...args) {
- /// f(static_cast<Types&&>(args)...);
- /// }
- /// \endcode
- ///
- /// Here, the argument to the function object \c f is a pack expansion whose
- /// pattern is \c static_cast<Types&&>(args). When the \c forward function
- /// template is instantiated, the pack expansion will instantiate to zero or
- /// or more function arguments to the function object \c f.
- class PackExpansionExpr : public Expr {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- SourceLocation EllipsisLoc;
- /// The number of expansions that will be produced by this pack
- /// expansion expression, if known.
- ///
- /// When zero, the number of expansions is not known. Otherwise, this value
- /// is the number of expansions + 1.
- unsigned NumExpansions;
- Stmt *Pattern;
- public:
- PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions)
- : Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
- Pattern->getObjectKind()),
- EllipsisLoc(EllipsisLoc),
- NumExpansions(NumExpansions ? *NumExpansions + 1 : 0),
- Pattern(Pattern) {
- setDependence(computeDependence(this));
- }
- PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {}
- /// Retrieve the pattern of the pack expansion.
- Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); }
- /// Retrieve the pattern of the pack expansion.
- const Expr *getPattern() const { return reinterpret_cast<Expr *>(Pattern); }
- /// Retrieve the location of the ellipsis that describes this pack
- /// expansion.
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- /// Determine the number of expansions that will be produced when
- /// this pack expansion is instantiated, if already known.
- Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
- return None;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return Pattern->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY { return EllipsisLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == PackExpansionExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(&Pattern, &Pattern + 1);
- }
- const_child_range children() const {
- return const_child_range(&Pattern, &Pattern + 1);
- }
- };
- /// Represents an expression that computes the length of a parameter
- /// pack.
- ///
- /// \code
- /// template<typename ...Types>
- /// struct count {
- /// static const unsigned value = sizeof...(Types);
- /// };
- /// \endcode
- class SizeOfPackExpr final
- : public Expr,
- private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend TrailingObjects;
- /// The location of the \c sizeof keyword.
- SourceLocation OperatorLoc;
- /// The location of the name of the parameter pack.
- SourceLocation PackLoc;
- /// The location of the closing parenthesis.
- SourceLocation RParenLoc;
- /// The length of the parameter pack, if known.
- ///
- /// When this expression is not value-dependent, this is the length of
- /// the pack. When the expression was parsed rather than instantiated
- /// (and thus is value-dependent), this is zero.
- ///
- /// After partial substitution into a sizeof...(X) expression (for instance,
- /// within an alias template or during function template argument deduction),
- /// we store a trailing array of partially-substituted TemplateArguments,
- /// and this is the length of that array.
- unsigned Length;
- /// The parameter pack.
- NamedDecl *Pack = nullptr;
- /// Create an expression that computes the length of
- /// the given parameter pack.
- SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
- SourceLocation PackLoc, SourceLocation RParenLoc,
- Optional<unsigned> Length,
- ArrayRef<TemplateArgument> PartialArgs)
- : Expr(SizeOfPackExprClass, SizeType, VK_PRValue, OK_Ordinary),
- OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
- Length(Length ? *Length : PartialArgs.size()), Pack(Pack) {
- assert((!Length || PartialArgs.empty()) &&
- "have partial args for non-dependent sizeof... expression");
- auto *Args = getTrailingObjects<TemplateArgument>();
- std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args);
- setDependence(Length ? ExprDependence::None
- : ExprDependence::ValueInstantiation);
- }
- /// Create an empty expression.
- SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs)
- : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {}
- public:
- static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc,
- NamedDecl *Pack, SourceLocation PackLoc,
- SourceLocation RParenLoc,
- Optional<unsigned> Length = None,
- ArrayRef<TemplateArgument> PartialArgs = None);
- static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
- unsigned NumPartialArgs);
- /// Determine the location of the 'sizeof' keyword.
- SourceLocation getOperatorLoc() const { return OperatorLoc; }
- /// Determine the location of the parameter pack.
- SourceLocation getPackLoc() const { return PackLoc; }
- /// Determine the location of the right parenthesis.
- SourceLocation getRParenLoc() const { return RParenLoc; }
- /// Retrieve the parameter pack.
- NamedDecl *getPack() const { return Pack; }
- /// Retrieve the length of the parameter pack.
- ///
- /// This routine may only be invoked when the expression is not
- /// value-dependent.
- unsigned getPackLength() const {
- assert(!isValueDependent() &&
- "Cannot get the length of a value-dependent pack size expression");
- return Length;
- }
- /// Determine whether this represents a partially-substituted sizeof...
- /// expression, such as is produced for:
- ///
- /// template<typename ...Ts> using X = int[sizeof...(Ts)];
- /// template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>);
- bool isPartiallySubstituted() const {
- return isValueDependent() && Length;
- }
- /// Get
- ArrayRef<TemplateArgument> getPartialArguments() const {
- assert(isPartiallySubstituted());
- const auto *Args = getTrailingObjects<TemplateArgument>();
- return llvm::makeArrayRef(Args, Args + Length);
- }
- SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SizeOfPackExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Represents a reference to a non-type template parameter
- /// that has been substituted with a template argument.
- class SubstNonTypeTemplateParmExpr : public Expr {
- friend class ASTReader;
- friend class ASTStmtReader;
- /// The replaced parameter and a flag indicating if it was a reference
- /// parameter. For class NTTPs, we can't determine that based on the value
- /// category alone.
- llvm::PointerIntPair<NonTypeTemplateParmDecl*, 1, bool> ParamAndRef;
- /// The replacement expression.
- Stmt *Replacement;
- explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
- public:
- SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
- SourceLocation Loc,
- NonTypeTemplateParmDecl *Param, bool RefParam,
- Expr *Replacement)
- : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
- ParamAndRef(Param, RefParam), Replacement(Replacement) {
- SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
- setDependence(computeDependence(this));
- }
- SourceLocation getNameLoc() const {
- return SubstNonTypeTemplateParmExprBits.NameLoc;
- }
- SourceLocation getBeginLoc() const { return getNameLoc(); }
- SourceLocation getEndLoc() const { return getNameLoc(); }
- Expr *getReplacement() const { return cast<Expr>(Replacement); }
- NonTypeTemplateParmDecl *getParameter() const {
- return ParamAndRef.getPointer();
- }
- bool isReferenceParameter() const { return ParamAndRef.getInt(); }
- /// Determine the substituted type of the template parameter.
- QualType getParameterType(const ASTContext &Ctx) const;
- static bool classof(const Stmt *s) {
- return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
- }
- // Iterators
- child_range children() { return child_range(&Replacement, &Replacement + 1); }
- const_child_range children() const {
- return const_child_range(&Replacement, &Replacement + 1);
- }
- };
- /// Represents a reference to a non-type template parameter pack that
- /// has been substituted with a non-template argument pack.
- ///
- /// When a pack expansion in the source code contains multiple parameter packs
- /// and those parameter packs correspond to different levels of template
- /// parameter lists, this node is used to represent a non-type template
- /// parameter pack from an outer level, which has already had its argument pack
- /// substituted but that still lives within a pack expansion that itself
- /// could not be instantiated. When actually performing a substitution into
- /// that pack expansion (e.g., when all template parameters have corresponding
- /// arguments), this type will be replaced with the appropriate underlying
- /// expression at the current pack substitution index.
- class SubstNonTypeTemplateParmPackExpr : public Expr {
- friend class ASTReader;
- friend class ASTStmtReader;
- /// The non-type template parameter pack itself.
- NonTypeTemplateParmDecl *Param;
- /// A pointer to the set of template arguments that this
- /// parameter pack is instantiated with.
- const TemplateArgument *Arguments;
- /// The number of template arguments in \c Arguments.
- unsigned NumArguments;
- /// The location of the non-type template parameter pack reference.
- SourceLocation NameLoc;
- explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty)
- : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {}
- public:
- SubstNonTypeTemplateParmPackExpr(QualType T,
- ExprValueKind ValueKind,
- NonTypeTemplateParmDecl *Param,
- SourceLocation NameLoc,
- const TemplateArgument &ArgPack);
- /// Retrieve the non-type template parameter pack being substituted.
- NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
- /// Retrieve the location of the parameter pack name.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
- /// Retrieve the template argument pack containing the substituted
- /// template arguments.
- TemplateArgument getArgumentPack() const;
- SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Represents a reference to a function parameter pack or init-capture pack
- /// that has been substituted but not yet expanded.
- ///
- /// When a pack expansion contains multiple parameter packs at different levels,
- /// this node is used to represent a function parameter pack at an outer level
- /// which we have already substituted to refer to expanded parameters, but where
- /// the containing pack expansion cannot yet be expanded.
- ///
- /// \code
- /// template<typename...Ts> struct S {
- /// template<typename...Us> auto f(Ts ...ts) -> decltype(g(Us(ts)...));
- /// };
- /// template struct S<int, int>;
- /// \endcode
- class FunctionParmPackExpr final
- : public Expr,
- private llvm::TrailingObjects<FunctionParmPackExpr, VarDecl *> {
- friend class ASTReader;
- friend class ASTStmtReader;
- friend TrailingObjects;
- /// The function parameter pack which was referenced.
- VarDecl *ParamPack;
- /// The location of the function parameter pack reference.
- SourceLocation NameLoc;
- /// The number of expansions of this pack.
- unsigned NumParameters;
- FunctionParmPackExpr(QualType T, VarDecl *ParamPack,
- SourceLocation NameLoc, unsigned NumParams,
- VarDecl *const *Params);
- public:
- static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T,
- VarDecl *ParamPack,
- SourceLocation NameLoc,
- ArrayRef<VarDecl *> Params);
- static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context,
- unsigned NumParams);
- /// Get the parameter pack which this expression refers to.
- VarDecl *getParameterPack() const { return ParamPack; }
- /// Get the location of the parameter pack.
- SourceLocation getParameterPackLocation() const { return NameLoc; }
- /// Iterators over the parameters which the parameter pack expanded
- /// into.
- using iterator = VarDecl * const *;
- iterator begin() const { return getTrailingObjects<VarDecl *>(); }
- iterator end() const { return begin() + NumParameters; }
- /// Get the number of parameters in this parameter pack.
- unsigned getNumExpansions() const { return NumParameters; }
- /// Get an expansion of the parameter pack by index.
- VarDecl *getExpansion(unsigned I) const { return begin()[I]; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return NameLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return NameLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == FunctionParmPackExprClass;
- }
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// Represents a prvalue temporary that is written into memory so that
- /// a reference can bind to it.
- ///
- /// Prvalue expressions are materialized when they need to have an address
- /// in memory for a reference to bind to. This happens when binding a
- /// reference to the result of a conversion, e.g.,
- ///
- /// \code
- /// const int &r = 1.0;
- /// \endcode
- ///
- /// Here, 1.0 is implicitly converted to an \c int. That resulting \c int is
- /// then materialized via a \c MaterializeTemporaryExpr, and the reference
- /// binds to the temporary. \c MaterializeTemporaryExprs are always glvalues
- /// (either an lvalue or an xvalue, depending on the kind of reference binding
- /// to it), maintaining the invariant that references always bind to glvalues.
- ///
- /// Reference binding and copy-elision can both extend the lifetime of a
- /// temporary. When either happens, the expression will also track the
- /// declaration which is responsible for the lifetime extension.
- class MaterializeTemporaryExpr : public Expr {
- private:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- llvm::PointerUnion<Stmt *, LifetimeExtendedTemporaryDecl *> State;
- public:
- MaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference,
- LifetimeExtendedTemporaryDecl *MTD = nullptr);
- MaterializeTemporaryExpr(EmptyShell Empty)
- : Expr(MaterializeTemporaryExprClass, Empty) {}
- /// Retrieve the temporary-generating subexpression whose value will
- /// be materialized into a glvalue.
- Expr *getSubExpr() const {
- return cast<Expr>(
- State.is<Stmt *>()
- ? State.get<Stmt *>()
- : State.get<LifetimeExtendedTemporaryDecl *>()->getTemporaryExpr());
- }
- /// Retrieve the storage duration for the materialized temporary.
- StorageDuration getStorageDuration() const {
- return State.is<Stmt *>() ? SD_FullExpression
- : State.get<LifetimeExtendedTemporaryDecl *>()
- ->getStorageDuration();
- }
- /// Get the storage for the constant value of a materialized temporary
- /// of static storage duration.
- APValue *getOrCreateValue(bool MayCreate) const {
- assert(State.is<LifetimeExtendedTemporaryDecl *>() &&
- "the temporary has not been lifetime extended");
- return State.get<LifetimeExtendedTemporaryDecl *>()->getOrCreateValue(
- MayCreate);
- }
- LifetimeExtendedTemporaryDecl *getLifetimeExtendedTemporaryDecl() {
- return State.dyn_cast<LifetimeExtendedTemporaryDecl *>();
- }
- const LifetimeExtendedTemporaryDecl *
- getLifetimeExtendedTemporaryDecl() const {
- return State.dyn_cast<LifetimeExtendedTemporaryDecl *>();
- }
- /// Get the declaration which triggered the lifetime-extension of this
- /// temporary, if any.
- ValueDecl *getExtendingDecl() {
- return State.is<Stmt *>() ? nullptr
- : State.get<LifetimeExtendedTemporaryDecl *>()
- ->getExtendingDecl();
- }
- const ValueDecl *getExtendingDecl() const {
- return const_cast<MaterializeTemporaryExpr *>(this)->getExtendingDecl();
- }
- void setExtendingDecl(ValueDecl *ExtendedBy, unsigned ManglingNumber);
- unsigned getManglingNumber() const {
- return State.is<Stmt *>() ? 0
- : State.get<LifetimeExtendedTemporaryDecl *>()
- ->getManglingNumber();
- }
- /// Determine whether this materialized temporary is bound to an
- /// lvalue reference; otherwise, it's bound to an rvalue reference.
- bool isBoundToLvalueReference() const { return isLValue(); }
- /// Determine whether this temporary object is usable in constant
- /// expressions, as specified in C++20 [expr.const]p4.
- bool isUsableInConstantExpressions(const ASTContext &Context) const;
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return getSubExpr()->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return getSubExpr()->getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MaterializeTemporaryExprClass;
- }
- // Iterators
- child_range children() {
- return State.is<Stmt *>()
- ? child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1)
- : State.get<LifetimeExtendedTemporaryDecl *>()->childrenExpr();
- }
- const_child_range children() const {
- return State.is<Stmt *>()
- ? const_child_range(State.getAddrOfPtr1(),
- State.getAddrOfPtr1() + 1)
- : const_cast<const LifetimeExtendedTemporaryDecl *>(
- State.get<LifetimeExtendedTemporaryDecl *>())
- ->childrenExpr();
- }
- };
- /// Represents a folding of a pack over an operator.
- ///
- /// This expression is always dependent and represents a pack expansion of the
- /// forms:
- ///
- /// ( expr op ... )
- /// ( ... op expr )
- /// ( expr op ... op expr )
- class CXXFoldExpr : public Expr {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- enum SubExpr { Callee, LHS, RHS, Count };
- SourceLocation LParenLoc;
- SourceLocation EllipsisLoc;
- SourceLocation RParenLoc;
- // When 0, the number of expansions is not known. Otherwise, this is one more
- // than the number of expansions.
- unsigned NumExpansions;
- Stmt *SubExprs[SubExpr::Count];
- BinaryOperatorKind Opcode;
- public:
- CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
- SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
- SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
- Optional<unsigned> NumExpansions)
- : Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary),
- LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
- NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
- SubExprs[SubExpr::Callee] = Callee;
- SubExprs[SubExpr::LHS] = LHS;
- SubExprs[SubExpr::RHS] = RHS;
- setDependence(computeDependence(this));
- }
- CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
- UnresolvedLookupExpr *getCallee() const {
- return static_cast<UnresolvedLookupExpr *>(SubExprs[SubExpr::Callee]);
- }
- Expr *getLHS() const { return static_cast<Expr*>(SubExprs[SubExpr::LHS]); }
- Expr *getRHS() const { return static_cast<Expr*>(SubExprs[SubExpr::RHS]); }
- /// Does this produce a right-associated sequence of operators?
- bool isRightFold() const {
- return getLHS() && getLHS()->containsUnexpandedParameterPack();
- }
- /// Does this produce a left-associated sequence of operators?
- bool isLeftFold() const { return !isRightFold(); }
- /// Get the pattern, that is, the operand that contains an unexpanded pack.
- Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); }
- /// Get the operand that doesn't contain a pack, for a binary fold.
- Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
- SourceLocation getLParenLoc() const { return LParenLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- BinaryOperatorKind getOperator() const { return Opcode; }
- Optional<unsigned> getNumExpansions() const {
- if (NumExpansions)
- return NumExpansions - 1;
- return None;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- if (LParenLoc.isValid())
- return LParenLoc;
- if (isLeftFold())
- return getEllipsisLoc();
- return getLHS()->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (RParenLoc.isValid())
- return RParenLoc;
- if (isRightFold())
- return getEllipsisLoc();
- return getRHS()->getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CXXFoldExprClass;
- }
- // Iterators
- child_range children() {
- return child_range(SubExprs, SubExprs + SubExpr::Count);
- }
- const_child_range children() const {
- return const_child_range(SubExprs, SubExprs + SubExpr::Count);
- }
- };
- /// Represents an expression that might suspend coroutine execution;
- /// either a co_await or co_yield expression.
- ///
- /// Evaluation of this expression first evaluates its 'ready' expression. If
- /// that returns 'false':
- /// -- execution of the coroutine is suspended
- /// -- the 'suspend' expression is evaluated
- /// -- if the 'suspend' expression returns 'false', the coroutine is
- /// resumed
- /// -- otherwise, control passes back to the resumer.
- /// If the coroutine is not suspended, or when it is resumed, the 'resume'
- /// expression is evaluated, and its result is the result of the overall
- /// expression.
- class CoroutineSuspendExpr : public Expr {
- friend class ASTStmtReader;
- SourceLocation KeywordLoc;
- enum SubExpr { Common, Ready, Suspend, Resume, Count };
- Stmt *SubExprs[SubExpr::Count];
- OpaqueValueExpr *OpaqueValue = nullptr;
- public:
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
- Expr *Ready, Expr *Suspend, Expr *Resume,
- OpaqueValueExpr *OpaqueValue)
- : Expr(SC, Resume->getType(), Resume->getValueKind(),
- Resume->getObjectKind()),
- KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = Ready;
- SubExprs[SubExpr::Suspend] = Suspend;
- SubExprs[SubExpr::Resume] = Resume;
- setDependence(computeDependence(this));
- }
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
- Expr *Common)
- : Expr(SC, Ty, VK_PRValue, OK_Ordinary), KeywordLoc(KeywordLoc) {
- assert(Common->isTypeDependent() && Ty->isDependentType() &&
- "wrong constructor for non-dependent co_await/co_yield expression");
- SubExprs[SubExpr::Common] = Common;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- setDependence(computeDependence(this));
- }
- CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
- SubExprs[SubExpr::Common] = nullptr;
- SubExprs[SubExpr::Ready] = nullptr;
- SubExprs[SubExpr::Suspend] = nullptr;
- SubExprs[SubExpr::Resume] = nullptr;
- }
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- Expr *getCommonExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Common]);
- }
- /// getOpaqueValue - Return the opaque value placeholder.
- OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; }
- Expr *getReadyExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Ready]);
- }
- Expr *getSuspendExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Suspend]);
- }
- Expr *getResumeExpr() const {
- return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
- }
- SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return getCommonExpr()->getEndLoc();
- }
- child_range children() {
- return child_range(SubExprs, SubExprs + SubExpr::Count);
- }
- const_child_range children() const {
- return const_child_range(SubExprs, SubExprs + SubExpr::Count);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass ||
- T->getStmtClass() == CoyieldExprClass;
- }
- };
- /// Represents a 'co_await' expression.
- class CoawaitExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
- public:
- CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue,
- bool IsImplicit = false)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
- Suspend, Resume, OpaqueValue) {
- CoawaitBits.IsImplicit = IsImplicit;
- }
- CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
- bool IsImplicit = false)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {
- CoawaitBits.IsImplicit = IsImplicit;
- }
- CoawaitExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
- bool isImplicit() const { return CoawaitBits.IsImplicit; }
- void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoawaitExprClass;
- }
- };
- /// Represents a 'co_await' expression while the type of the promise
- /// is dependent.
- class DependentCoawaitExpr : public Expr {
- friend class ASTStmtReader;
- SourceLocation KeywordLoc;
- Stmt *SubExprs[2];
- public:
- DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op,
- UnresolvedLookupExpr *OpCoawait)
- : Expr(DependentCoawaitExprClass, Ty, VK_PRValue, OK_Ordinary),
- KeywordLoc(KeywordLoc) {
- // NOTE: A co_await expression is dependent on the coroutines promise
- // type and may be dependent even when the `Op` expression is not.
- assert(Ty->isDependentType() &&
- "wrong constructor for non-dependent co_await/co_yield expression");
- SubExprs[0] = Op;
- SubExprs[1] = OpCoawait;
- setDependence(computeDependence(this));
- }
- DependentCoawaitExpr(EmptyShell Empty)
- : Expr(DependentCoawaitExprClass, Empty) {}
- Expr *getOperand() const { return cast<Expr>(SubExprs[0]); }
- UnresolvedLookupExpr *getOperatorCoawaitLookup() const {
- return cast<UnresolvedLookupExpr>(SubExprs[1]);
- }
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return getOperand()->getEndLoc();
- }
- child_range children() { return child_range(SubExprs, SubExprs + 2); }
- const_child_range children() const {
- return const_child_range(SubExprs, SubExprs + 2);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DependentCoawaitExprClass;
- }
- };
- /// Represents a 'co_yield' expression.
- class CoyieldExpr : public CoroutineSuspendExpr {
- friend class ASTStmtReader;
- public:
- CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
- Suspend, Resume, OpaqueValue) {}
- CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
- CoyieldExpr(EmptyShell Empty)
- : CoroutineSuspendExpr(CoyieldExprClass, Empty) {}
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CoyieldExprClass;
- }
- };
- /// Represents a C++2a __builtin_bit_cast(T, v) expression. Used to implement
- /// std::bit_cast. These can sometimes be evaluated as part of a constant
- /// expression, but otherwise CodeGen to a simple memcpy in general.
- class BuiltinBitCastExpr final
- : public ExplicitCastExpr,
- private llvm::TrailingObjects<BuiltinBitCastExpr, CXXBaseSpecifier *> {
- friend class ASTStmtReader;
- friend class CastExpr;
- friend TrailingObjects;
- SourceLocation KWLoc;
- SourceLocation RParenLoc;
- public:
- BuiltinBitCastExpr(QualType T, ExprValueKind VK, CastKind CK, Expr *SrcExpr,
- TypeSourceInfo *DstType, SourceLocation KWLoc,
- SourceLocation RParenLoc)
- : ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, false,
- DstType),
- KWLoc(KWLoc), RParenLoc(RParenLoc) {}
- BuiltinBitCastExpr(EmptyShell Empty)
- : ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0, false) {}
- SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BuiltinBitCastExprClass;
- }
- };
- } // namespace clang
- #endif // LLVM_CLANG_AST_EXPRCXX_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|