12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- Stmt.h - Classes for representing statements -------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the Stmt interface and subclasses.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_STMT_H
- #define LLVM_CLANG_AST_STMT_H
- #include "clang/AST/DeclGroup.h"
- #include "clang/AST/DependenceFlags.h"
- #include "clang/AST/StmtIterator.h"
- #include "clang/Basic/CapturedStmt.h"
- #include "clang/Basic/IdentifierTable.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/SourceLocation.h"
- #include "clang/Basic/Specifiers.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/BitmaskEnum.h"
- #include "llvm/ADT/PointerIntPair.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/iterator.h"
- #include "llvm/ADT/iterator_range.h"
- #include "llvm/Support/Casting.h"
- #include "llvm/Support/Compiler.h"
- #include "llvm/Support/ErrorHandling.h"
- #include <algorithm>
- #include <cassert>
- #include <cstddef>
- #include <iterator>
- #include <string>
- namespace llvm {
- class FoldingSetNodeID;
- } // namespace llvm
- namespace clang {
- class ASTContext;
- class Attr;
- class CapturedDecl;
- class Decl;
- class Expr;
- class AddrLabelExpr;
- class LabelDecl;
- class ODRHash;
- class PrinterHelper;
- struct PrintingPolicy;
- class RecordDecl;
- class SourceManager;
- class StringLiteral;
- class Token;
- class VarDecl;
- //===----------------------------------------------------------------------===//
- // AST classes for statements.
- //===----------------------------------------------------------------------===//
- /// Stmt - This represents one statement.
- ///
- class alignas(void *) Stmt {
- public:
- enum StmtClass {
- NoStmtClass = 0,
- #define STMT(CLASS, PARENT) CLASS##Class,
- #define STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
- #define LAST_STMT_RANGE(BASE, FIRST, LAST) \
- first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
- #define ABSTRACT_STMT(STMT)
- #include "clang/AST/StmtNodes.inc"
- };
- // Make vanilla 'new' and 'delete' illegal for Stmts.
- protected:
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- void *operator new(size_t bytes) noexcept {
- llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
- }
- void operator delete(void *data) noexcept {
- llvm_unreachable("Stmts cannot be released with regular 'delete'.");
- }
- //===--- Statement bitfields classes ---===//
- class StmtBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class Stmt;
- /// The statement class.
- unsigned sClass : 8;
- };
- enum { NumStmtBits = 8 };
- class NullStmtBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class NullStmt;
- unsigned : NumStmtBits;
- /// True if the null statement was preceded by an empty macro, e.g:
- /// @code
- /// #define CALL(x)
- /// CALL(0);
- /// @endcode
- unsigned HasLeadingEmptyMacro : 1;
- /// The location of the semi-colon.
- SourceLocation SemiLoc;
- };
- class CompoundStmtBitfields {
- friend class ASTStmtReader;
- friend class CompoundStmt;
- unsigned : NumStmtBits;
- unsigned NumStmts : 32 - NumStmtBits;
- /// The location of the opening "{".
- SourceLocation LBraceLoc;
- };
- class LabelStmtBitfields {
- friend class LabelStmt;
- unsigned : NumStmtBits;
- SourceLocation IdentLoc;
- };
- class AttributedStmtBitfields {
- friend class ASTStmtReader;
- friend class AttributedStmt;
- unsigned : NumStmtBits;
- /// Number of attributes.
- unsigned NumAttrs : 32 - NumStmtBits;
- /// The location of the attribute.
- SourceLocation AttrLoc;
- };
- class IfStmtBitfields {
- friend class ASTStmtReader;
- friend class IfStmt;
- unsigned : NumStmtBits;
- /// Whether this is a constexpr if, or a consteval if, or neither.
- unsigned Kind : 3;
- /// True if this if statement has storage for an else statement.
- unsigned HasElse : 1;
- /// True if this if statement has storage for a variable declaration.
- unsigned HasVar : 1;
- /// True if this if statement has storage for an init statement.
- unsigned HasInit : 1;
- /// The location of the "if".
- SourceLocation IfLoc;
- };
- class SwitchStmtBitfields {
- friend class SwitchStmt;
- unsigned : NumStmtBits;
- /// True if the SwitchStmt has storage for an init statement.
- unsigned HasInit : 1;
- /// True if the SwitchStmt has storage for a condition variable.
- unsigned HasVar : 1;
- /// If the SwitchStmt is a switch on an enum value, records whether all
- /// the enum values were covered by CaseStmts. The coverage information
- /// value is meant to be a hint for possible clients.
- unsigned AllEnumCasesCovered : 1;
- /// The location of the "switch".
- SourceLocation SwitchLoc;
- };
- class WhileStmtBitfields {
- friend class ASTStmtReader;
- friend class WhileStmt;
- unsigned : NumStmtBits;
- /// True if the WhileStmt has storage for a condition variable.
- unsigned HasVar : 1;
- /// The location of the "while".
- SourceLocation WhileLoc;
- };
- class DoStmtBitfields {
- friend class DoStmt;
- unsigned : NumStmtBits;
- /// The location of the "do".
- SourceLocation DoLoc;
- };
- class ForStmtBitfields {
- friend class ForStmt;
- unsigned : NumStmtBits;
- /// The location of the "for".
- SourceLocation ForLoc;
- };
- class GotoStmtBitfields {
- friend class GotoStmt;
- friend class IndirectGotoStmt;
- unsigned : NumStmtBits;
- /// The location of the "goto".
- SourceLocation GotoLoc;
- };
- class ContinueStmtBitfields {
- friend class ContinueStmt;
- unsigned : NumStmtBits;
- /// The location of the "continue".
- SourceLocation ContinueLoc;
- };
- class BreakStmtBitfields {
- friend class BreakStmt;
- unsigned : NumStmtBits;
- /// The location of the "break".
- SourceLocation BreakLoc;
- };
- class ReturnStmtBitfields {
- friend class ReturnStmt;
- unsigned : NumStmtBits;
- /// True if this ReturnStmt has storage for an NRVO candidate.
- unsigned HasNRVOCandidate : 1;
- /// The location of the "return".
- SourceLocation RetLoc;
- };
- class SwitchCaseBitfields {
- friend class SwitchCase;
- friend class CaseStmt;
- unsigned : NumStmtBits;
- /// Used by CaseStmt to store whether it is a case statement
- /// of the form case LHS ... RHS (a GNU extension).
- unsigned CaseStmtIsGNURange : 1;
- /// The location of the "case" or "default" keyword.
- SourceLocation KeywordLoc;
- };
- //===--- Expression bitfields classes ---===//
- class ExprBitfields {
- friend class ASTStmtReader; // deserialization
- friend class AtomicExpr; // ctor
- friend class BlockDeclRefExpr; // ctor
- friend class CallExpr; // ctor
- friend class CXXConstructExpr; // ctor
- friend class CXXDependentScopeMemberExpr; // ctor
- friend class CXXNewExpr; // ctor
- friend class CXXUnresolvedConstructExpr; // ctor
- friend class DeclRefExpr; // computeDependence
- friend class DependentScopeDeclRefExpr; // ctor
- friend class DesignatedInitExpr; // ctor
- friend class Expr;
- friend class InitListExpr; // ctor
- friend class ObjCArrayLiteral; // ctor
- friend class ObjCDictionaryLiteral; // ctor
- friend class ObjCMessageExpr; // ctor
- friend class OffsetOfExpr; // ctor
- friend class OpaqueValueExpr; // ctor
- friend class OverloadExpr; // ctor
- friend class ParenListExpr; // ctor
- friend class PseudoObjectExpr; // ctor
- friend class ShuffleVectorExpr; // ctor
- unsigned : NumStmtBits;
- unsigned ValueKind : 2;
- unsigned ObjectKind : 3;
- unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>;
- };
- enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> };
- class ConstantExprBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class ConstantExpr;
- unsigned : NumExprBits;
- /// The kind of result that is tail-allocated.
- unsigned ResultKind : 2;
- /// The kind of Result as defined by APValue::Kind.
- unsigned APValueKind : 4;
- /// When ResultKind == RSK_Int64, true if the tail-allocated integer is
- /// unsigned.
- unsigned IsUnsigned : 1;
- /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated
- /// integer. 7 bits because it is the minimal number of bits to represent a
- /// value from 0 to 64 (the size of the tail-allocated integer).
- unsigned BitWidth : 7;
- /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the
- /// tail-allocated APValue.
- unsigned HasCleanup : 1;
- /// True if this ConstantExpr was created for immediate invocation.
- unsigned IsImmediateInvocation : 1;
- };
- class PredefinedExprBitfields {
- friend class ASTStmtReader;
- friend class PredefinedExpr;
- unsigned : NumExprBits;
- /// The kind of this PredefinedExpr. One of the enumeration values
- /// in PredefinedExpr::IdentKind.
- unsigned Kind : 4;
- /// True if this PredefinedExpr has a trailing "StringLiteral *"
- /// for the predefined identifier.
- unsigned HasFunctionName : 1;
- /// The location of this PredefinedExpr.
- SourceLocation Loc;
- };
- class DeclRefExprBitfields {
- friend class ASTStmtReader; // deserialization
- friend class DeclRefExpr;
- unsigned : NumExprBits;
- unsigned HasQualifier : 1;
- unsigned HasTemplateKWAndArgsInfo : 1;
- unsigned HasFoundDecl : 1;
- unsigned HadMultipleCandidates : 1;
- unsigned RefersToEnclosingVariableOrCapture : 1;
- unsigned NonOdrUseReason : 2;
- /// The location of the declaration name itself.
- SourceLocation Loc;
- };
- class FloatingLiteralBitfields {
- friend class FloatingLiteral;
- unsigned : NumExprBits;
- unsigned Semantics : 3; // Provides semantics for APFloat construction
- unsigned IsExact : 1;
- };
- class StringLiteralBitfields {
- friend class ASTStmtReader;
- friend class StringLiteral;
- unsigned : NumExprBits;
- /// The kind of this string literal.
- /// One of the enumeration values of StringLiteral::StringKind.
- unsigned Kind : 3;
- /// The width of a single character in bytes. Only values of 1, 2,
- /// and 4 bytes are supported. StringLiteral::mapCharByteWidth maps
- /// the target + string kind to the appropriate CharByteWidth.
- unsigned CharByteWidth : 3;
- unsigned IsPascal : 1;
- /// The number of concatenated token this string is made of.
- /// This is the number of trailing SourceLocation.
- unsigned NumConcatenated;
- };
- class CharacterLiteralBitfields {
- friend class CharacterLiteral;
- unsigned : NumExprBits;
- unsigned Kind : 3;
- };
- class UnaryOperatorBitfields {
- friend class UnaryOperator;
- unsigned : NumExprBits;
- unsigned Opc : 5;
- unsigned CanOverflow : 1;
- //
- /// This is only meaningful for operations on floating point
- /// types when additional values need to be in trailing storage.
- /// It is 0 otherwise.
- unsigned HasFPFeatures : 1;
- SourceLocation Loc;
- };
- class UnaryExprOrTypeTraitExprBitfields {
- friend class UnaryExprOrTypeTraitExpr;
- unsigned : NumExprBits;
- unsigned Kind : 3;
- unsigned IsType : 1; // true if operand is a type, false if an expression.
- };
- class ArrayOrMatrixSubscriptExprBitfields {
- friend class ArraySubscriptExpr;
- friend class MatrixSubscriptExpr;
- unsigned : NumExprBits;
- SourceLocation RBracketLoc;
- };
- class CallExprBitfields {
- friend class CallExpr;
- unsigned : NumExprBits;
- unsigned NumPreArgs : 1;
- /// True if the callee of the call expression was found using ADL.
- unsigned UsesADL : 1;
- /// True if the call expression has some floating-point features.
- unsigned HasFPFeatures : 1;
- /// Padding used to align OffsetToTrailingObjects to a byte multiple.
- unsigned : 24 - 3 - NumExprBits;
- /// The offset in bytes from the this pointer to the start of the
- /// trailing objects belonging to CallExpr. Intentionally byte sized
- /// for faster access.
- unsigned OffsetToTrailingObjects : 8;
- };
- enum { NumCallExprBits = 32 };
- class MemberExprBitfields {
- friend class ASTStmtReader;
- friend class MemberExpr;
- unsigned : NumExprBits;
- /// IsArrow - True if this is "X->F", false if this is "X.F".
- unsigned IsArrow : 1;
- /// True if this member expression used a nested-name-specifier to
- /// refer to the member, e.g., "x->Base::f", or found its member via
- /// a using declaration. When true, a MemberExprNameQualifier
- /// structure is allocated immediately after the MemberExpr.
- unsigned HasQualifierOrFoundDecl : 1;
- /// True if this member expression specified a template keyword
- /// and/or a template argument list explicitly, e.g., x->f<int>,
- /// x->template f, x->template f<int>.
- /// When true, an ASTTemplateKWAndArgsInfo structure and its
- /// TemplateArguments (if any) are present.
- unsigned HasTemplateKWAndArgsInfo : 1;
- /// True if this member expression refers to a method that
- /// was resolved from an overloaded set having size greater than 1.
- unsigned HadMultipleCandidates : 1;
- /// Value of type NonOdrUseReason indicating why this MemberExpr does
- /// not constitute an odr-use of the named declaration. Meaningful only
- /// when naming a static member.
- unsigned NonOdrUseReason : 2;
- /// This is the location of the -> or . in the expression.
- SourceLocation OperatorLoc;
- };
- class CastExprBitfields {
- friend class CastExpr;
- friend class ImplicitCastExpr;
- unsigned : NumExprBits;
- unsigned Kind : 7;
- unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
- /// True if the call expression has some floating-point features.
- unsigned HasFPFeatures : 1;
- /// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
- /// here. ([implimits] Direct and indirect base classes [16384]).
- unsigned BasePathSize;
- };
- class BinaryOperatorBitfields {
- friend class BinaryOperator;
- unsigned : NumExprBits;
- unsigned Opc : 6;
- /// This is only meaningful for operations on floating point
- /// types when additional values need to be in trailing storage.
- /// It is 0 otherwise.
- unsigned HasFPFeatures : 1;
- SourceLocation OpLoc;
- };
- class InitListExprBitfields {
- friend class InitListExpr;
- unsigned : NumExprBits;
- /// Whether this initializer list originally had a GNU array-range
- /// designator in it. This is a temporary marker used by CodeGen.
- unsigned HadArrayRangeDesignator : 1;
- };
- class ParenListExprBitfields {
- friend class ASTStmtReader;
- friend class ParenListExpr;
- unsigned : NumExprBits;
- /// The number of expressions in the paren list.
- unsigned NumExprs;
- };
- class GenericSelectionExprBitfields {
- friend class ASTStmtReader;
- friend class GenericSelectionExpr;
- unsigned : NumExprBits;
- /// The location of the "_Generic".
- SourceLocation GenericLoc;
- };
- class PseudoObjectExprBitfields {
- friend class ASTStmtReader; // deserialization
- friend class PseudoObjectExpr;
- unsigned : NumExprBits;
- // These don't need to be particularly wide, because they're
- // strictly limited by the forms of expressions we permit.
- unsigned NumSubExprs : 8;
- unsigned ResultIndex : 32 - 8 - NumExprBits;
- };
- class SourceLocExprBitfields {
- friend class ASTStmtReader;
- friend class SourceLocExpr;
- unsigned : NumExprBits;
- /// The kind of source location builtin represented by the SourceLocExpr.
- /// Ex. __builtin_LINE, __builtin_FUNCTION, ect.
- unsigned Kind : 2;
- };
- class StmtExprBitfields {
- friend class ASTStmtReader;
- friend class StmtExpr;
- unsigned : NumExprBits;
- /// The number of levels of template parameters enclosing this statement
- /// expression. Used to determine if a statement expression remains
- /// dependent after instantiation.
- unsigned TemplateDepth;
- };
- //===--- C++ Expression bitfields classes ---===//
- class CXXOperatorCallExprBitfields {
- friend class ASTStmtReader;
- friend class CXXOperatorCallExpr;
- unsigned : NumCallExprBits;
- /// The kind of this overloaded operator. One of the enumerator
- /// value of OverloadedOperatorKind.
- unsigned OperatorKind : 6;
- };
- class CXXRewrittenBinaryOperatorBitfields {
- friend class ASTStmtReader;
- friend class CXXRewrittenBinaryOperator;
- unsigned : NumCallExprBits;
- unsigned IsReversed : 1;
- };
- class CXXBoolLiteralExprBitfields {
- friend class CXXBoolLiteralExpr;
- unsigned : NumExprBits;
- /// The value of the boolean literal.
- unsigned Value : 1;
- /// The location of the boolean literal.
- SourceLocation Loc;
- };
- class CXXNullPtrLiteralExprBitfields {
- friend class CXXNullPtrLiteralExpr;
- unsigned : NumExprBits;
- /// The location of the null pointer literal.
- SourceLocation Loc;
- };
- class CXXThisExprBitfields {
- friend class CXXThisExpr;
- unsigned : NumExprBits;
- /// Whether this is an implicit "this".
- unsigned IsImplicit : 1;
- /// The location of the "this".
- SourceLocation Loc;
- };
- class CXXThrowExprBitfields {
- friend class ASTStmtReader;
- friend class CXXThrowExpr;
- unsigned : NumExprBits;
- /// Whether the thrown variable (if any) is in scope.
- unsigned IsThrownVariableInScope : 1;
- /// The location of the "throw".
- SourceLocation ThrowLoc;
- };
- class CXXDefaultArgExprBitfields {
- friend class ASTStmtReader;
- friend class CXXDefaultArgExpr;
- unsigned : NumExprBits;
- /// The location where the default argument expression was used.
- SourceLocation Loc;
- };
- class CXXDefaultInitExprBitfields {
- friend class ASTStmtReader;
- friend class CXXDefaultInitExpr;
- unsigned : NumExprBits;
- /// The location where the default initializer expression was used.
- SourceLocation Loc;
- };
- class CXXScalarValueInitExprBitfields {
- friend class ASTStmtReader;
- friend class CXXScalarValueInitExpr;
- unsigned : NumExprBits;
- SourceLocation RParenLoc;
- };
- class CXXNewExprBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class CXXNewExpr;
- unsigned : NumExprBits;
- /// Was the usage ::new, i.e. is the global new to be used?
- unsigned IsGlobalNew : 1;
- /// Do we allocate an array? If so, the first trailing "Stmt *" is the
- /// size expression.
- unsigned IsArray : 1;
- /// Should the alignment be passed to the allocation function?
- unsigned ShouldPassAlignment : 1;
- /// If this is an array allocation, does the usual deallocation
- /// function for the allocated type want to know the allocated size?
- unsigned UsualArrayDeleteWantsSize : 1;
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
- unsigned StoredInitializationStyle : 2;
- /// True if the allocated type was expressed as a parenthesized type-id.
- unsigned IsParenTypeId : 1;
- /// The number of placement new arguments.
- unsigned NumPlacementArgs;
- };
- class CXXDeleteExprBitfields {
- friend class ASTStmtReader;
- friend class CXXDeleteExpr;
- unsigned : NumExprBits;
- /// Is this a forced global delete, i.e. "::delete"?
- unsigned GlobalDelete : 1;
- /// Is this the array form of delete, i.e. "delete[]"?
- unsigned ArrayForm : 1;
- /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is
- /// applied to pointer-to-array type (ArrayFormAsWritten will be false
- /// while ArrayForm will be true).
- unsigned ArrayFormAsWritten : 1;
- /// Does the usual deallocation function for the element type require
- /// a size_t argument?
- unsigned UsualArrayDeleteWantsSize : 1;
- /// Location of the expression.
- SourceLocation Loc;
- };
- class TypeTraitExprBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class TypeTraitExpr;
- unsigned : NumExprBits;
- /// The kind of type trait, which is a value of a TypeTrait enumerator.
- unsigned Kind : 8;
- /// If this expression is not value-dependent, this indicates whether
- /// the trait evaluated true or false.
- unsigned Value : 1;
- /// The number of arguments to this type trait. According to [implimits]
- /// 8 bits would be enough, but we require (and test for) at least 16 bits
- /// to mirror FunctionType.
- unsigned NumArgs;
- };
- class DependentScopeDeclRefExprBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class DependentScopeDeclRefExpr;
- unsigned : NumExprBits;
- /// Whether the name includes info for explicit template
- /// keyword and arguments.
- unsigned HasTemplateKWAndArgsInfo : 1;
- };
- class CXXConstructExprBitfields {
- friend class ASTStmtReader;
- friend class CXXConstructExpr;
- unsigned : NumExprBits;
- unsigned Elidable : 1;
- unsigned HadMultipleCandidates : 1;
- unsigned ListInitialization : 1;
- unsigned StdInitListInitialization : 1;
- unsigned ZeroInitialization : 1;
- unsigned ConstructionKind : 3;
- SourceLocation Loc;
- };
- class ExprWithCleanupsBitfields {
- friend class ASTStmtReader; // deserialization
- friend class ExprWithCleanups;
- unsigned : NumExprBits;
- // When false, it must not have side effects.
- unsigned CleanupsHaveSideEffects : 1;
- unsigned NumObjects : 32 - 1 - NumExprBits;
- };
- class CXXUnresolvedConstructExprBitfields {
- friend class ASTStmtReader;
- friend class CXXUnresolvedConstructExpr;
- unsigned : NumExprBits;
- /// The number of arguments used to construct the type.
- unsigned NumArgs;
- };
- class CXXDependentScopeMemberExprBitfields {
- friend class ASTStmtReader;
- friend class CXXDependentScopeMemberExpr;
- unsigned : NumExprBits;
- /// Whether this member expression used the '->' operator or
- /// the '.' operator.
- unsigned IsArrow : 1;
- /// Whether this member expression has info for explicit template
- /// keyword and arguments.
- unsigned HasTemplateKWAndArgsInfo : 1;
- /// See getFirstQualifierFoundInScope() and the comment listing
- /// the trailing objects.
- unsigned HasFirstQualifierFoundInScope : 1;
- /// The location of the '->' or '.' operator.
- SourceLocation OperatorLoc;
- };
- class OverloadExprBitfields {
- friend class ASTStmtReader;
- friend class OverloadExpr;
- unsigned : NumExprBits;
- /// Whether the name includes info for explicit template
- /// keyword and arguments.
- unsigned HasTemplateKWAndArgsInfo : 1;
- /// Padding used by the derived classes to store various bits. If you
- /// need to add some data here, shrink this padding and add your data
- /// above. NumOverloadExprBits also needs to be updated.
- unsigned : 32 - NumExprBits - 1;
- /// The number of results.
- unsigned NumResults;
- };
- enum { NumOverloadExprBits = NumExprBits + 1 };
- class UnresolvedLookupExprBitfields {
- friend class ASTStmtReader;
- friend class UnresolvedLookupExpr;
- unsigned : NumOverloadExprBits;
- /// True if these lookup results should be extended by
- /// argument-dependent lookup if this is the operand of a function call.
- unsigned RequiresADL : 1;
- /// True if these lookup results are overloaded. This is pretty trivially
- /// rederivable if we urgently need to kill this field.
- unsigned Overloaded : 1;
- };
- static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
- "UnresolvedLookupExprBitfields must be <= than 4 bytes to"
- "avoid trashing OverloadExprBitfields::NumResults!");
- class UnresolvedMemberExprBitfields {
- friend class ASTStmtReader;
- friend class UnresolvedMemberExpr;
- unsigned : NumOverloadExprBits;
- /// Whether this member expression used the '->' operator or
- /// the '.' operator.
- unsigned IsArrow : 1;
- /// Whether the lookup results contain an unresolved using declaration.
- unsigned HasUnresolvedUsing : 1;
- };
- static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
- "UnresolvedMemberExprBitfields must be <= than 4 bytes to"
- "avoid trashing OverloadExprBitfields::NumResults!");
- class CXXNoexceptExprBitfields {
- friend class ASTStmtReader;
- friend class CXXNoexceptExpr;
- unsigned : NumExprBits;
- unsigned Value : 1;
- };
- class SubstNonTypeTemplateParmExprBitfields {
- friend class ASTStmtReader;
- friend class SubstNonTypeTemplateParmExpr;
- unsigned : NumExprBits;
- /// The location of the non-type template parameter reference.
- SourceLocation NameLoc;
- };
- class LambdaExprBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class LambdaExpr;
- unsigned : NumExprBits;
- /// The default capture kind, which is a value of type
- /// LambdaCaptureDefault.
- unsigned CaptureDefault : 2;
- /// Whether this lambda had an explicit parameter list vs. an
- /// implicit (and empty) parameter list.
- unsigned ExplicitParams : 1;
- /// Whether this lambda had the result type explicitly specified.
- unsigned ExplicitResultType : 1;
- /// The number of captures.
- unsigned NumCaptures : 16;
- };
- class RequiresExprBitfields {
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
- friend class RequiresExpr;
- unsigned : NumExprBits;
- unsigned IsSatisfied : 1;
- SourceLocation RequiresKWLoc;
- };
- //===--- C++ Coroutines TS bitfields classes ---===//
- class CoawaitExprBitfields {
- friend class CoawaitExpr;
- unsigned : NumExprBits;
- unsigned IsImplicit : 1;
- };
- //===--- Obj-C Expression bitfields classes ---===//
- class ObjCIndirectCopyRestoreExprBitfields {
- friend class ObjCIndirectCopyRestoreExpr;
- unsigned : NumExprBits;
- unsigned ShouldCopy : 1;
- };
- //===--- Clang Extensions bitfields classes ---===//
- class OpaqueValueExprBitfields {
- friend class ASTStmtReader;
- friend class OpaqueValueExpr;
- unsigned : NumExprBits;
- /// The OVE is a unique semantic reference to its source expression if this
- /// bit is set to true.
- unsigned IsUnique : 1;
- SourceLocation Loc;
- };
- union {
- // Same order as in StmtNodes.td.
- // Statements
- StmtBitfields StmtBits;
- NullStmtBitfields NullStmtBits;
- CompoundStmtBitfields CompoundStmtBits;
- LabelStmtBitfields LabelStmtBits;
- AttributedStmtBitfields AttributedStmtBits;
- IfStmtBitfields IfStmtBits;
- SwitchStmtBitfields SwitchStmtBits;
- WhileStmtBitfields WhileStmtBits;
- DoStmtBitfields DoStmtBits;
- ForStmtBitfields ForStmtBits;
- GotoStmtBitfields GotoStmtBits;
- ContinueStmtBitfields ContinueStmtBits;
- BreakStmtBitfields BreakStmtBits;
- ReturnStmtBitfields ReturnStmtBits;
- SwitchCaseBitfields SwitchCaseBits;
- // Expressions
- ExprBitfields ExprBits;
- ConstantExprBitfields ConstantExprBits;
- PredefinedExprBitfields PredefinedExprBits;
- DeclRefExprBitfields DeclRefExprBits;
- FloatingLiteralBitfields FloatingLiteralBits;
- StringLiteralBitfields StringLiteralBits;
- CharacterLiteralBitfields CharacterLiteralBits;
- UnaryOperatorBitfields UnaryOperatorBits;
- UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
- ArrayOrMatrixSubscriptExprBitfields ArrayOrMatrixSubscriptExprBits;
- CallExprBitfields CallExprBits;
- MemberExprBitfields MemberExprBits;
- CastExprBitfields CastExprBits;
- BinaryOperatorBitfields BinaryOperatorBits;
- InitListExprBitfields InitListExprBits;
- ParenListExprBitfields ParenListExprBits;
- GenericSelectionExprBitfields GenericSelectionExprBits;
- PseudoObjectExprBitfields PseudoObjectExprBits;
- SourceLocExprBitfields SourceLocExprBits;
- // GNU Extensions.
- StmtExprBitfields StmtExprBits;
- // C++ Expressions
- CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
- CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits;
- CXXBoolLiteralExprBitfields CXXBoolLiteralExprBits;
- CXXNullPtrLiteralExprBitfields CXXNullPtrLiteralExprBits;
- CXXThisExprBitfields CXXThisExprBits;
- CXXThrowExprBitfields CXXThrowExprBits;
- CXXDefaultArgExprBitfields CXXDefaultArgExprBits;
- CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
- CXXScalarValueInitExprBitfields CXXScalarValueInitExprBits;
- CXXNewExprBitfields CXXNewExprBits;
- CXXDeleteExprBitfields CXXDeleteExprBits;
- TypeTraitExprBitfields TypeTraitExprBits;
- DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits;
- CXXConstructExprBitfields CXXConstructExprBits;
- ExprWithCleanupsBitfields ExprWithCleanupsBits;
- CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
- CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
- OverloadExprBitfields OverloadExprBits;
- UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
- UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
- CXXNoexceptExprBitfields CXXNoexceptExprBits;
- SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
- LambdaExprBitfields LambdaExprBits;
- RequiresExprBitfields RequiresExprBits;
- // C++ Coroutines TS expressions
- CoawaitExprBitfields CoawaitBits;
- // Obj-C Expressions
- ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
- // Clang Extensions
- OpaqueValueExprBitfields OpaqueValueExprBits;
- };
- public:
- // Only allow allocation of Stmts using the allocator in ASTContext
- // or by doing a placement new.
- void* operator new(size_t bytes, const ASTContext& C,
- unsigned alignment = 8);
- void* operator new(size_t bytes, const ASTContext* C,
- unsigned alignment = 8) {
- return operator new(bytes, *C, alignment);
- }
- void *operator new(size_t bytes, void *mem) noexcept { return mem; }
- void operator delete(void *, const ASTContext &, unsigned) noexcept {}
- void operator delete(void *, const ASTContext *, unsigned) noexcept {}
- void operator delete(void *, size_t) noexcept {}
- void operator delete(void *, void *) noexcept {}
- public:
- /// A placeholder type used to construct an empty shell of a
- /// type, that will be filled in later (e.g., by some
- /// de-serialization).
- struct EmptyShell {};
- /// The likelihood of a branch being taken.
- enum Likelihood {
- LH_Unlikely = -1, ///< Branch has the [[unlikely]] attribute.
- LH_None, ///< No attribute set or branches of the IfStmt have
- ///< the same attribute.
- LH_Likely ///< Branch has the [[likely]] attribute.
- };
- protected:
- /// Iterator for iterating over Stmt * arrays that contain only T *.
- ///
- /// This is needed because AST nodes use Stmt* arrays to store
- /// references to children (to be compatible with StmtIterator).
- template<typename T, typename TPtr = T *, typename StmtPtr = Stmt *>
- struct CastIterator
- : llvm::iterator_adaptor_base<CastIterator<T, TPtr, StmtPtr>, StmtPtr *,
- std::random_access_iterator_tag, TPtr> {
- using Base = typename CastIterator::iterator_adaptor_base;
- CastIterator() : Base(nullptr) {}
- CastIterator(StmtPtr *I) : Base(I) {}
- typename Base::value_type operator*() const {
- return cast_or_null<T>(*this->I);
- }
- };
- /// Const iterator for iterating over Stmt * arrays that contain only T *.
- template <typename T>
- using ConstCastIterator = CastIterator<T, const T *const, const Stmt *const>;
- using ExprIterator = CastIterator<Expr>;
- using ConstExprIterator = ConstCastIterator<Expr>;
- private:
- /// Whether statistic collection is enabled.
- static bool StatisticsEnabled;
- protected:
- /// Construct an empty statement.
- explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}
- public:
- Stmt() = delete;
- Stmt(const Stmt &) = delete;
- Stmt(Stmt &&) = delete;
- Stmt &operator=(const Stmt &) = delete;
- Stmt &operator=(Stmt &&) = delete;
- Stmt(StmtClass SC) {
- static_assert(sizeof(*this) <= 8,
- "changing bitfields changed sizeof(Stmt)");
- static_assert(sizeof(*this) % alignof(void *) == 0,
- "Insufficient alignment!");
- StmtBits.sClass = SC;
- if (StatisticsEnabled) Stmt::addStmtClass(SC);
- }
- StmtClass getStmtClass() const {
- return static_cast<StmtClass>(StmtBits.sClass);
- }
- const char *getStmtClassName() const;
- /// SourceLocation tokens are not useful in isolation - they are low level
- /// value objects created/interpreted by SourceManager. We assume AST
- /// clients will have a pointer to the respective SourceManager.
- SourceRange getSourceRange() const LLVM_READONLY;
- SourceLocation getBeginLoc() const LLVM_READONLY;
- SourceLocation getEndLoc() const LLVM_READONLY;
- // global temp stats (until we have a per-module visitor)
- static void addStmtClass(const StmtClass s);
- static void EnableStatistics();
- static void PrintStats();
- /// \returns the likelihood of a set of attributes.
- static Likelihood getLikelihood(ArrayRef<const Attr *> Attrs);
- /// \returns the likelihood of a statement.
- static Likelihood getLikelihood(const Stmt *S);
- /// \returns the likelihood attribute of a statement.
- static const Attr *getLikelihoodAttr(const Stmt *S);
- /// \returns the likelihood of the 'then' branch of an 'if' statement. The
- /// 'else' branch is required to determine whether both branches specify the
- /// same likelihood, which affects the result.
- static Likelihood getLikelihood(const Stmt *Then, const Stmt *Else);
- /// \returns whether the likelihood of the branches of an if statement are
- /// conflicting. When the first element is \c true there's a conflict and
- /// the Attr's are the conflicting attributes of the Then and Else Stmt.
- static std::tuple<bool, const Attr *, const Attr *>
- determineLikelihoodConflict(const Stmt *Then, const Stmt *Else);
- /// Dumps the specified AST fragment and all subtrees to
- /// \c llvm::errs().
- void dump() const;
- void dump(raw_ostream &OS, const ASTContext &Context) const;
- /// \return Unique reproducible object identifier
- int64_t getID(const ASTContext &Context) const;
- /// dumpColor - same as dump(), but forces color highlighting.
- void dumpColor() const;
- /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
- /// back to its original source language syntax.
- void dumpPretty(const ASTContext &Context) const;
- void printPretty(raw_ostream &OS, PrinterHelper *Helper,
- const PrintingPolicy &Policy, unsigned Indentation = 0,
- StringRef NewlineSymbol = "\n",
- const ASTContext *Context = nullptr) const;
- void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper,
- const PrintingPolicy &Policy,
- unsigned Indentation = 0,
- StringRef NewlineSymbol = "\n",
- const ASTContext *Context = nullptr) const;
- /// Pretty-prints in JSON format.
- void printJson(raw_ostream &Out, PrinterHelper *Helper,
- const PrintingPolicy &Policy, bool AddQuotes) const;
- /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
- /// works on systems with GraphViz (Mac OS X) or dot+gv installed.
- void viewAST() const;
- /// Skip no-op (attributed, compound) container stmts and skip captured
- /// stmt at the top, if \a IgnoreCaptured is true.
- Stmt *IgnoreContainers(bool IgnoreCaptured = false);
- const Stmt *IgnoreContainers(bool IgnoreCaptured = false) const {
- return const_cast<Stmt *>(this)->IgnoreContainers(IgnoreCaptured);
- }
- const Stmt *stripLabelLikeStatements() const;
- Stmt *stripLabelLikeStatements() {
- return const_cast<Stmt*>(
- const_cast<const Stmt*>(this)->stripLabelLikeStatements());
- }
- /// Child Iterators: All subclasses must implement 'children'
- /// to permit easy iteration over the substatements/subexpessions of an
- /// AST node. This permits easy iteration over all nodes in the AST.
- using child_iterator = StmtIterator;
- using const_child_iterator = ConstStmtIterator;
- using child_range = llvm::iterator_range<child_iterator>;
- using const_child_range = llvm::iterator_range<const_child_iterator>;
- child_range children();
- const_child_range children() const {
- auto Children = const_cast<Stmt *>(this)->children();
- return const_child_range(Children.begin(), Children.end());
- }
- child_iterator child_begin() { return children().begin(); }
- child_iterator child_end() { return children().end(); }
- const_child_iterator child_begin() const { return children().begin(); }
- const_child_iterator child_end() const { return children().end(); }
- /// Produce a unique representation of the given statement.
- ///
- /// \param ID once the profiling operation is complete, will contain
- /// the unique representation of the given statement.
- ///
- /// \param Context the AST context in which the statement resides
- ///
- /// \param Canonical whether the profile should be based on the canonical
- /// representation of this statement (e.g., where non-type template
- /// parameters are identified by index/level rather than their
- /// declaration pointers) or the exact representation of the statement as
- /// written in the source.
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- bool Canonical) const;
- /// Calculate a unique representation for a statement that is
- /// stable across compiler invocations.
- ///
- /// \param ID profile information will be stored in ID.
- ///
- /// \param Hash an ODRHash object which will be called where pointers would
- /// have been used in the Profile function.
- void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
- };
- /// DeclStmt - Adaptor class for mixing declarations with statements and
- /// expressions. For example, CompoundStmt mixes statements, expressions
- /// and declarations (variables, types). Another example is ForStmt, where
- /// the first statement can be an expression or a declaration.
- class DeclStmt : public Stmt {
- DeclGroupRef DG;
- SourceLocation StartLoc, EndLoc;
- public:
- DeclStmt(DeclGroupRef dg, SourceLocation startLoc, SourceLocation endLoc)
- : Stmt(DeclStmtClass), DG(dg), StartLoc(startLoc), EndLoc(endLoc) {}
- /// Build an empty declaration statement.
- explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) {}
- /// isSingleDecl - This method returns true if this DeclStmt refers
- /// to a single Decl.
- bool isSingleDecl() const { return DG.isSingleDecl(); }
- const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
- Decl *getSingleDecl() { return DG.getSingleDecl(); }
- const DeclGroupRef getDeclGroup() const { return DG; }
- DeclGroupRef getDeclGroup() { return DG; }
- void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
- void setStartLoc(SourceLocation L) { StartLoc = L; }
- SourceLocation getEndLoc() const { return EndLoc; }
- void setEndLoc(SourceLocation L) { EndLoc = L; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return StartLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclStmtClass;
- }
- // Iterators over subexpressions.
- child_range children() {
- return child_range(child_iterator(DG.begin(), DG.end()),
- child_iterator(DG.end(), DG.end()));
- }
- const_child_range children() const {
- auto Children = const_cast<DeclStmt *>(this)->children();
- return const_child_range(Children);
- }
- using decl_iterator = DeclGroupRef::iterator;
- using const_decl_iterator = DeclGroupRef::const_iterator;
- using decl_range = llvm::iterator_range<decl_iterator>;
- using decl_const_range = llvm::iterator_range<const_decl_iterator>;
- decl_range decls() { return decl_range(decl_begin(), decl_end()); }
- decl_const_range decls() const {
- return decl_const_range(decl_begin(), decl_end());
- }
- decl_iterator decl_begin() { return DG.begin(); }
- decl_iterator decl_end() { return DG.end(); }
- const_decl_iterator decl_begin() const { return DG.begin(); }
- const_decl_iterator decl_end() const { return DG.end(); }
- using reverse_decl_iterator = std::reverse_iterator<decl_iterator>;
- reverse_decl_iterator decl_rbegin() {
- return reverse_decl_iterator(decl_end());
- }
- reverse_decl_iterator decl_rend() {
- return reverse_decl_iterator(decl_begin());
- }
- };
- /// NullStmt - This is the null statement ";": C99 6.8.3p3.
- ///
- class NullStmt : public Stmt {
- public:
- NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
- : Stmt(NullStmtClass) {
- NullStmtBits.HasLeadingEmptyMacro = hasLeadingEmptyMacro;
- setSemiLoc(L);
- }
- /// Build an empty null statement.
- explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}
- SourceLocation getSemiLoc() const { return NullStmtBits.SemiLoc; }
- void setSemiLoc(SourceLocation L) { NullStmtBits.SemiLoc = L; }
- bool hasLeadingEmptyMacro() const {
- return NullStmtBits.HasLeadingEmptyMacro;
- }
- SourceLocation getBeginLoc() const { return getSemiLoc(); }
- SourceLocation getEndLoc() const { return getSemiLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == NullStmtClass;
- }
- 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());
- }
- };
- /// CompoundStmt - This represents a group of statements like { stmt stmt }.
- class CompoundStmt final : public Stmt,
- private llvm::TrailingObjects<CompoundStmt, Stmt *> {
- friend class ASTStmtReader;
- friend TrailingObjects;
- /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
- SourceLocation RBraceLoc;
- CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB, SourceLocation RB);
- explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
- void setStmts(ArrayRef<Stmt *> Stmts);
- public:
- static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
- SourceLocation LB, SourceLocation RB);
- // Build an empty compound statement with a location.
- explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
- CompoundStmtBits.NumStmts = 0;
- CompoundStmtBits.LBraceLoc = Loc;
- }
- // Build an empty compound statement.
- static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts);
- bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
- unsigned size() const { return CompoundStmtBits.NumStmts; }
- using body_iterator = Stmt **;
- using body_range = llvm::iterator_range<body_iterator>;
- body_range body() { return body_range(body_begin(), body_end()); }
- body_iterator body_begin() { return getTrailingObjects<Stmt *>(); }
- body_iterator body_end() { return body_begin() + size(); }
- Stmt *body_front() { return !body_empty() ? body_begin()[0] : nullptr; }
- Stmt *body_back() {
- return !body_empty() ? body_begin()[size() - 1] : nullptr;
- }
- using const_body_iterator = Stmt *const *;
- using body_const_range = llvm::iterator_range<const_body_iterator>;
- body_const_range body() const {
- return body_const_range(body_begin(), body_end());
- }
- const_body_iterator body_begin() const {
- return getTrailingObjects<Stmt *>();
- }
- const_body_iterator body_end() const { return body_begin() + size(); }
- const Stmt *body_front() const {
- return !body_empty() ? body_begin()[0] : nullptr;
- }
- const Stmt *body_back() const {
- return !body_empty() ? body_begin()[size() - 1] : nullptr;
- }
- using reverse_body_iterator = std::reverse_iterator<body_iterator>;
- reverse_body_iterator body_rbegin() {
- return reverse_body_iterator(body_end());
- }
- reverse_body_iterator body_rend() {
- return reverse_body_iterator(body_begin());
- }
- using const_reverse_body_iterator =
- std::reverse_iterator<const_body_iterator>;
- const_reverse_body_iterator body_rbegin() const {
- return const_reverse_body_iterator(body_end());
- }
- const_reverse_body_iterator body_rend() const {
- return const_reverse_body_iterator(body_begin());
- }
- // Get the Stmt that StmtExpr would consider to be the result of this
- // compound statement. This is used by StmtExpr to properly emulate the GCC
- // compound expression extension, which ignores trailing NullStmts when
- // getting the result of the expression.
- // i.e. ({ 5;;; })
- // ^^ ignored
- // If we don't find something that isn't a NullStmt, just return the last
- // Stmt.
- Stmt *getStmtExprResult() {
- for (auto *B : llvm::reverse(body())) {
- if (!isa<NullStmt>(B))
- return B;
- }
- return body_back();
- }
- const Stmt *getStmtExprResult() const {
- return const_cast<CompoundStmt *>(this)->getStmtExprResult();
- }
- SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
- SourceLocation getEndLoc() const { return RBraceLoc; }
- SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; }
- SourceLocation getRBracLoc() const { return RBraceLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CompoundStmtClass;
- }
- // Iterators
- child_range children() { return child_range(body_begin(), body_end()); }
- const_child_range children() const {
- return const_child_range(body_begin(), body_end());
- }
- };
- // SwitchCase is the base class for CaseStmt and DefaultStmt,
- class SwitchCase : public Stmt {
- protected:
- /// The location of the ":".
- SourceLocation ColonLoc;
- // The location of the "case" or "default" keyword. Stored in SwitchCaseBits.
- // SourceLocation KeywordLoc;
- /// A pointer to the following CaseStmt or DefaultStmt class,
- /// used by SwitchStmt.
- SwitchCase *NextSwitchCase = nullptr;
- SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
- : Stmt(SC), ColonLoc(ColonLoc) {
- setKeywordLoc(KWLoc);
- }
- SwitchCase(StmtClass SC, EmptyShell) : Stmt(SC) {}
- public:
- const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
- SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
- void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
- SourceLocation getKeywordLoc() const { return SwitchCaseBits.KeywordLoc; }
- void setKeywordLoc(SourceLocation L) { SwitchCaseBits.KeywordLoc = L; }
- SourceLocation getColonLoc() const { return ColonLoc; }
- void setColonLoc(SourceLocation L) { ColonLoc = L; }
- inline Stmt *getSubStmt();
- const Stmt *getSubStmt() const {
- return const_cast<SwitchCase *>(this)->getSubStmt();
- }
- SourceLocation getBeginLoc() const { return getKeywordLoc(); }
- inline SourceLocation getEndLoc() const LLVM_READONLY;
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass ||
- T->getStmtClass() == DefaultStmtClass;
- }
- };
- /// CaseStmt - Represent a case statement. It can optionally be a GNU case
- /// statement of the form LHS ... RHS representing a range of cases.
- class CaseStmt final
- : public SwitchCase,
- private llvm::TrailingObjects<CaseStmt, Stmt *, SourceLocation> {
- friend TrailingObjects;
- // CaseStmt is followed by several trailing objects, some of which optional.
- // Note that it would be more convenient to put the optional trailing objects
- // at the end but this would impact children().
- // The trailing objects are in order:
- //
- // * A "Stmt *" for the LHS of the case statement. Always present.
- //
- // * A "Stmt *" for the RHS of the case statement. This is a GNU extension
- // which allow ranges in cases statement of the form LHS ... RHS.
- // Present if and only if caseStmtIsGNURange() is true.
- //
- // * A "Stmt *" for the substatement of the case statement. Always present.
- //
- // * A SourceLocation for the location of the ... if this is a case statement
- // with a range. Present if and only if caseStmtIsGNURange() is true.
- enum { LhsOffset = 0, SubStmtOffsetFromRhs = 1 };
- enum { NumMandatoryStmtPtr = 2 };
- unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumMandatoryStmtPtr + caseStmtIsGNURange();
- }
- unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
- return caseStmtIsGNURange();
- }
- unsigned lhsOffset() const { return LhsOffset; }
- unsigned rhsOffset() const { return LhsOffset + caseStmtIsGNURange(); }
- unsigned subStmtOffset() const { return rhsOffset() + SubStmtOffsetFromRhs; }
- /// Build a case statement assuming that the storage for the
- /// trailing objects has been properly allocated.
- CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
- SourceLocation ellipsisLoc, SourceLocation colonLoc)
- : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
- // Handle GNU case statements of the form LHS ... RHS.
- bool IsGNURange = rhs != nullptr;
- SwitchCaseBits.CaseStmtIsGNURange = IsGNURange;
- setLHS(lhs);
- setSubStmt(nullptr);
- if (IsGNURange) {
- setRHS(rhs);
- setEllipsisLoc(ellipsisLoc);
- }
- }
- /// Build an empty switch case statement.
- explicit CaseStmt(EmptyShell Empty, bool CaseStmtIsGNURange)
- : SwitchCase(CaseStmtClass, Empty) {
- SwitchCaseBits.CaseStmtIsGNURange = CaseStmtIsGNURange;
- }
- public:
- /// Build a case statement.
- static CaseStmt *Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
- SourceLocation caseLoc, SourceLocation ellipsisLoc,
- SourceLocation colonLoc);
- /// Build an empty case statement.
- static CaseStmt *CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange);
- /// True if this case statement is of the form case LHS ... RHS, which
- /// is a GNU extension. In this case the RHS can be obtained with getRHS()
- /// and the location of the ellipsis can be obtained with getEllipsisLoc().
- bool caseStmtIsGNURange() const { return SwitchCaseBits.CaseStmtIsGNURange; }
- SourceLocation getCaseLoc() const { return getKeywordLoc(); }
- void setCaseLoc(SourceLocation L) { setKeywordLoc(L); }
- /// Get the location of the ... in a case statement of the form LHS ... RHS.
- SourceLocation getEllipsisLoc() const {
- return caseStmtIsGNURange() ? *getTrailingObjects<SourceLocation>()
- : SourceLocation();
- }
- /// Set the location of the ... in a case statement of the form LHS ... RHS.
- /// Assert that this case statement is of this form.
- void setEllipsisLoc(SourceLocation L) {
- assert(
- caseStmtIsGNURange() &&
- "setEllipsisLoc but this is not a case stmt of the form LHS ... RHS!");
- *getTrailingObjects<SourceLocation>() = L;
- }
- Expr *getLHS() {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
- }
- const Expr *getLHS() const {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
- }
- void setLHS(Expr *Val) {
- getTrailingObjects<Stmt *>()[lhsOffset()] = reinterpret_cast<Stmt *>(Val);
- }
- Expr *getRHS() {
- return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
- getTrailingObjects<Stmt *>()[rhsOffset()])
- : nullptr;
- }
- const Expr *getRHS() const {
- return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
- getTrailingObjects<Stmt *>()[rhsOffset()])
- : nullptr;
- }
- void setRHS(Expr *Val) {
- assert(caseStmtIsGNURange() &&
- "setRHS but this is not a case stmt of the form LHS ... RHS!");
- getTrailingObjects<Stmt *>()[rhsOffset()] = reinterpret_cast<Stmt *>(Val);
- }
- Stmt *getSubStmt() { return getTrailingObjects<Stmt *>()[subStmtOffset()]; }
- const Stmt *getSubStmt() const {
- return getTrailingObjects<Stmt *>()[subStmtOffset()];
- }
- void setSubStmt(Stmt *S) {
- getTrailingObjects<Stmt *>()[subStmtOffset()] = S;
- }
- SourceLocation getBeginLoc() const { return getKeywordLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY {
- // Handle deeply nested case statements with iteration instead of recursion.
- const CaseStmt *CS = this;
- while (const auto *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
- CS = CS2;
- return CS->getSubStmt()->getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CaseStmtClass;
- }
- // Iterators
- child_range children() {
- return child_range(getTrailingObjects<Stmt *>(),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- const_child_range children() const {
- return const_child_range(getTrailingObjects<Stmt *>(),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- };
- class DefaultStmt : public SwitchCase {
- Stmt *SubStmt;
- public:
- DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt)
- : SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
- /// Build an empty default statement.
- explicit DefaultStmt(EmptyShell Empty)
- : SwitchCase(DefaultStmtClass, Empty) {}
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
- void setSubStmt(Stmt *S) { SubStmt = S; }
- SourceLocation getDefaultLoc() const { return getKeywordLoc(); }
- void setDefaultLoc(SourceLocation L) { setKeywordLoc(L); }
- SourceLocation getBeginLoc() const { return getKeywordLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return SubStmt->getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DefaultStmtClass;
- }
- // Iterators
- child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
- const_child_range children() const {
- return const_child_range(&SubStmt, &SubStmt + 1);
- }
- };
- SourceLocation SwitchCase::getEndLoc() const {
- if (const auto *CS = dyn_cast<CaseStmt>(this))
- return CS->getEndLoc();
- else if (const auto *DS = dyn_cast<DefaultStmt>(this))
- return DS->getEndLoc();
- llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
- }
- Stmt *SwitchCase::getSubStmt() {
- if (auto *CS = dyn_cast<CaseStmt>(this))
- return CS->getSubStmt();
- else if (auto *DS = dyn_cast<DefaultStmt>(this))
- return DS->getSubStmt();
- llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
- }
- /// Represents a statement that could possibly have a value and type. This
- /// covers expression-statements, as well as labels and attributed statements.
- ///
- /// Value statements have a special meaning when they are the last non-null
- /// statement in a GNU statement expression, where they determine the value
- /// of the statement expression.
- class ValueStmt : public Stmt {
- protected:
- using Stmt::Stmt;
- public:
- const Expr *getExprStmt() const;
- Expr *getExprStmt() {
- const ValueStmt *ConstThis = this;
- return const_cast<Expr*>(ConstThis->getExprStmt());
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() >= firstValueStmtConstant &&
- T->getStmtClass() <= lastValueStmtConstant;
- }
- };
- /// LabelStmt - Represents a label, which has a substatement. For example:
- /// foo: return;
- class LabelStmt : public ValueStmt {
- LabelDecl *TheDecl;
- Stmt *SubStmt;
- bool SideEntry = false;
- public:
- /// Build a label statement.
- LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
- : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
- setIdentLoc(IL);
- }
- /// Build an empty label statement.
- explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {}
- SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; }
- void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; }
- LabelDecl *getDecl() const { return TheDecl; }
- void setDecl(LabelDecl *D) { TheDecl = D; }
- const char *getName() const;
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
- void setSubStmt(Stmt *SS) { SubStmt = SS; }
- SourceLocation getBeginLoc() const { return getIdentLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}
- child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
- const_child_range children() const {
- return const_child_range(&SubStmt, &SubStmt + 1);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == LabelStmtClass;
- }
- bool isSideEntry() const { return SideEntry; }
- void setSideEntry(bool SE) { SideEntry = SE; }
- };
- /// Represents an attribute applied to a statement.
- ///
- /// Represents an attribute applied to a statement. For example:
- /// [[omp::for(...)]] for (...) { ... }
- class AttributedStmt final
- : public ValueStmt,
- private llvm::TrailingObjects<AttributedStmt, const Attr *> {
- friend class ASTStmtReader;
- friend TrailingObjects;
- Stmt *SubStmt;
- AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs,
- Stmt *SubStmt)
- : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) {
- AttributedStmtBits.NumAttrs = Attrs.size();
- AttributedStmtBits.AttrLoc = Loc;
- std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
- }
- explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
- : ValueStmt(AttributedStmtClass, Empty) {
- AttributedStmtBits.NumAttrs = NumAttrs;
- AttributedStmtBits.AttrLoc = SourceLocation{};
- std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
- }
- const Attr *const *getAttrArrayPtr() const {
- return getTrailingObjects<const Attr *>();
- }
- const Attr **getAttrArrayPtr() { return getTrailingObjects<const Attr *>(); }
- public:
- static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
- ArrayRef<const Attr *> Attrs, Stmt *SubStmt);
- // Build an empty attributed statement.
- static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
- SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; }
- ArrayRef<const Attr *> getAttrs() const {
- return llvm::makeArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
- }
- Stmt *getSubStmt() { return SubStmt; }
- const Stmt *getSubStmt() const { return SubStmt; }
- SourceLocation getBeginLoc() const { return getAttrLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}
- child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
- const_child_range children() const {
- return const_child_range(&SubStmt, &SubStmt + 1);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == AttributedStmtClass;
- }
- };
- /// IfStmt - This represents an if/then/else.
- class IfStmt final
- : public Stmt,
- private llvm::TrailingObjects<IfStmt, Stmt *, SourceLocation> {
- friend TrailingObjects;
- // IfStmt is followed by several trailing objects, some of which optional.
- // Note that it would be more convenient to put the optional trailing
- // objects at then end but this would change the order of the children.
- // The trailing objects are in order:
- //
- // * A "Stmt *" for the init statement.
- // Present if and only if hasInitStorage().
- //
- // * A "Stmt *" for the condition variable.
- // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
- //
- // * A "Stmt *" for the condition.
- // Always present. This is in fact a "Expr *".
- //
- // * A "Stmt *" for the then statement.
- // Always present.
- //
- // * A "Stmt *" for the else statement.
- // Present if and only if hasElseStorage().
- //
- // * A "SourceLocation" for the location of the "else".
- // Present if and only if hasElseStorage().
- enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 };
- enum { NumMandatoryStmtPtr = 2 };
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
- unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumMandatoryStmtPtr + hasElseStorage() + hasVarStorage() +
- hasInitStorage();
- }
- unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
- return hasElseStorage();
- }
- unsigned initOffset() const { return InitOffset; }
- unsigned varOffset() const { return InitOffset + hasInitStorage(); }
- unsigned condOffset() const {
- return InitOffset + hasInitStorage() + hasVarStorage();
- }
- unsigned thenOffset() const { return condOffset() + ThenOffsetFromCond; }
- unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; }
- /// Build an if/then/else statement.
- IfStmt(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind,
- Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc,
- SourceLocation RParenLoc, Stmt *Then, SourceLocation EL, Stmt *Else);
- /// Build an empty if/then/else statement.
- explicit IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit);
- public:
- /// Create an IfStmt.
- static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL,
- IfStatementKind Kind, Stmt *Init, VarDecl *Var,
- Expr *Cond, SourceLocation LPL, SourceLocation RPL,
- Stmt *Then, SourceLocation EL = SourceLocation(),
- Stmt *Else = nullptr);
- /// Create an empty IfStmt optionally with storage for an else statement,
- /// condition variable and init expression.
- static IfStmt *CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
- bool HasInit);
- /// True if this IfStmt has the storage for an init statement.
- bool hasInitStorage() const { return IfStmtBits.HasInit; }
- /// True if this IfStmt has storage for a variable declaration.
- bool hasVarStorage() const { return IfStmtBits.HasVar; }
- /// True if this IfStmt has storage for an else statement.
- bool hasElseStorage() const { return IfStmtBits.HasElse; }
- Expr *getCond() {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
- }
- const Expr *getCond() const {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
- }
- void setCond(Expr *Cond) {
- getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
- }
- Stmt *getThen() { return getTrailingObjects<Stmt *>()[thenOffset()]; }
- const Stmt *getThen() const {
- return getTrailingObjects<Stmt *>()[thenOffset()];
- }
- void setThen(Stmt *Then) {
- getTrailingObjects<Stmt *>()[thenOffset()] = Then;
- }
- Stmt *getElse() {
- return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
- : nullptr;
- }
- const Stmt *getElse() const {
- return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
- : nullptr;
- }
- void setElse(Stmt *Else) {
- assert(hasElseStorage() &&
- "This if statement has no storage for an else statement!");
- getTrailingObjects<Stmt *>()[elseOffset()] = Else;
- }
- /// Retrieve the variable declared in this "if" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// if (int x = foo()) {
- /// printf("x is %d", x);
- /// }
- /// \endcode
- VarDecl *getConditionVariable();
- const VarDecl *getConditionVariable() const {
- return const_cast<IfStmt *>(this)->getConditionVariable();
- }
- /// Set the condition variable for this if statement.
- /// The if statement must have storage for the condition variable.
- void setConditionVariable(const ASTContext &Ctx, VarDecl *V);
- /// If this IfStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- DeclStmt *getConditionVariableDeclStmt() {
- return hasVarStorage() ? static_cast<DeclStmt *>(
- getTrailingObjects<Stmt *>()[varOffset()])
- : nullptr;
- }
- const DeclStmt *getConditionVariableDeclStmt() const {
- return hasVarStorage() ? static_cast<DeclStmt *>(
- getTrailingObjects<Stmt *>()[varOffset()])
- : nullptr;
- }
- Stmt *getInit() {
- return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
- : nullptr;
- }
- const Stmt *getInit() const {
- return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
- : nullptr;
- }
- void setInit(Stmt *Init) {
- assert(hasInitStorage() &&
- "This if statement has no storage for an init statement!");
- getTrailingObjects<Stmt *>()[initOffset()] = Init;
- }
- SourceLocation getIfLoc() const { return IfStmtBits.IfLoc; }
- void setIfLoc(SourceLocation IfLoc) { IfStmtBits.IfLoc = IfLoc; }
- SourceLocation getElseLoc() const {
- return hasElseStorage() ? *getTrailingObjects<SourceLocation>()
- : SourceLocation();
- }
- void setElseLoc(SourceLocation ElseLoc) {
- assert(hasElseStorage() &&
- "This if statement has no storage for an else statement!");
- *getTrailingObjects<SourceLocation>() = ElseLoc;
- }
- bool isConsteval() const {
- return getStatementKind() == IfStatementKind::ConstevalNonNegated ||
- getStatementKind() == IfStatementKind::ConstevalNegated;
- }
- bool isNonNegatedConsteval() const {
- return getStatementKind() == IfStatementKind::ConstevalNonNegated;
- }
- bool isNegatedConsteval() const {
- return getStatementKind() == IfStatementKind::ConstevalNegated;
- }
- bool isConstexpr() const {
- return getStatementKind() == IfStatementKind::Constexpr;
- }
- void setStatementKind(IfStatementKind Kind) {
- IfStmtBits.Kind = static_cast<unsigned>(Kind);
- }
- IfStatementKind getStatementKind() const {
- return static_cast<IfStatementKind>(IfStmtBits.Kind);
- }
- /// If this is an 'if constexpr', determine which substatement will be taken.
- /// Otherwise, or if the condition is value-dependent, returns None.
- Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const;
- Optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx);
- bool isObjCAvailabilityCheck() const;
- SourceLocation getBeginLoc() const { return getIfLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY {
- if (getElse())
- return getElse()->getEndLoc();
- return getThen()->getEndLoc();
- }
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- // Iterators over subexpressions. The iterators will include iterating
- // over the initialization expression referenced by the condition variable.
- child_range children() {
- // We always store a condition, but there is none for consteval if
- // statements, so skip it.
- return child_range(getTrailingObjects<Stmt *>() +
- (isConsteval() ? thenOffset() : 0),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- const_child_range children() const {
- // We always store a condition, but there is none for consteval if
- // statements, so skip it.
- return const_child_range(getTrailingObjects<Stmt *>() +
- (isConsteval() ? thenOffset() : 0),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IfStmtClass;
- }
- };
- /// SwitchStmt - This represents a 'switch' stmt.
- class SwitchStmt final : public Stmt,
- private llvm::TrailingObjects<SwitchStmt, Stmt *> {
- friend TrailingObjects;
- /// Points to a linked list of case and default statements.
- SwitchCase *FirstCase = nullptr;
- // SwitchStmt is followed by several trailing objects,
- // some of which optional. Note that it would be more convenient to
- // put the optional trailing objects at the end but this would change
- // the order in children().
- // The trailing objects are in order:
- //
- // * A "Stmt *" for the init statement.
- // Present if and only if hasInitStorage().
- //
- // * A "Stmt *" for the condition variable.
- // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
- //
- // * A "Stmt *" for the condition.
- // Always present. This is in fact an "Expr *".
- //
- // * A "Stmt *" for the body.
- // Always present.
- enum { InitOffset = 0, BodyOffsetFromCond = 1 };
- enum { NumMandatoryStmtPtr = 2 };
- SourceLocation LParenLoc;
- SourceLocation RParenLoc;
- unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumMandatoryStmtPtr + hasInitStorage() + hasVarStorage();
- }
- unsigned initOffset() const { return InitOffset; }
- unsigned varOffset() const { return InitOffset + hasInitStorage(); }
- unsigned condOffset() const {
- return InitOffset + hasInitStorage() + hasVarStorage();
- }
- unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
- /// Build a switch statement.
- SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond,
- SourceLocation LParenLoc, SourceLocation RParenLoc);
- /// Build a empty switch statement.
- explicit SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar);
- public:
- /// Create a switch statement.
- static SwitchStmt *Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
- Expr *Cond, SourceLocation LParenLoc,
- SourceLocation RParenLoc);
- /// Create an empty switch statement optionally with storage for
- /// an init expression and a condition variable.
- static SwitchStmt *CreateEmpty(const ASTContext &Ctx, bool HasInit,
- bool HasVar);
- /// True if this SwitchStmt has storage for an init statement.
- bool hasInitStorage() const { return SwitchStmtBits.HasInit; }
- /// True if this SwitchStmt has storage for a condition variable.
- bool hasVarStorage() const { return SwitchStmtBits.HasVar; }
- Expr *getCond() {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
- }
- const Expr *getCond() const {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
- }
- void setCond(Expr *Cond) {
- getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
- }
- Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
- const Stmt *getBody() const {
- return getTrailingObjects<Stmt *>()[bodyOffset()];
- }
- void setBody(Stmt *Body) {
- getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
- }
- Stmt *getInit() {
- return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
- : nullptr;
- }
- const Stmt *getInit() const {
- return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
- : nullptr;
- }
- void setInit(Stmt *Init) {
- assert(hasInitStorage() &&
- "This switch statement has no storage for an init statement!");
- getTrailingObjects<Stmt *>()[initOffset()] = Init;
- }
- /// Retrieve the variable declared in this "switch" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// switch (int x = foo()) {
- /// case 0: break;
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable();
- const VarDecl *getConditionVariable() const {
- return const_cast<SwitchStmt *>(this)->getConditionVariable();
- }
- /// Set the condition variable in this switch statement.
- /// The switch statement must have storage for it.
- void setConditionVariable(const ASTContext &Ctx, VarDecl *VD);
- /// If this SwitchStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- DeclStmt *getConditionVariableDeclStmt() {
- return hasVarStorage() ? static_cast<DeclStmt *>(
- getTrailingObjects<Stmt *>()[varOffset()])
- : nullptr;
- }
- const DeclStmt *getConditionVariableDeclStmt() const {
- return hasVarStorage() ? static_cast<DeclStmt *>(
- getTrailingObjects<Stmt *>()[varOffset()])
- : nullptr;
- }
- SwitchCase *getSwitchCaseList() { return FirstCase; }
- const SwitchCase *getSwitchCaseList() const { return FirstCase; }
- void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
- SourceLocation getSwitchLoc() const { return SwitchStmtBits.SwitchLoc; }
- void setSwitchLoc(SourceLocation L) { SwitchStmtBits.SwitchLoc = L; }
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- void setBody(Stmt *S, SourceLocation SL) {
- setBody(S);
- setSwitchLoc(SL);
- }
- void addSwitchCase(SwitchCase *SC) {
- assert(!SC->getNextSwitchCase() &&
- "case/default already added to a switch");
- SC->setNextSwitchCase(FirstCase);
- FirstCase = SC;
- }
- /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
- /// switch over an enum value then all cases have been explicitly covered.
- void setAllEnumCasesCovered() { SwitchStmtBits.AllEnumCasesCovered = true; }
- /// Returns true if the SwitchStmt is a switch of an enum value and all cases
- /// have been explicitly covered.
- bool isAllEnumCasesCovered() const {
- return SwitchStmtBits.AllEnumCasesCovered;
- }
- SourceLocation getBeginLoc() const { return getSwitchLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return getBody() ? getBody()->getEndLoc()
- : reinterpret_cast<const Stmt *>(getCond())->getEndLoc();
- }
- // Iterators
- child_range children() {
- return child_range(getTrailingObjects<Stmt *>(),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- const_child_range children() const {
- return const_child_range(getTrailingObjects<Stmt *>(),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SwitchStmtClass;
- }
- };
- /// WhileStmt - This represents a 'while' stmt.
- class WhileStmt final : public Stmt,
- private llvm::TrailingObjects<WhileStmt, Stmt *> {
- friend TrailingObjects;
- // WhileStmt is followed by several trailing objects,
- // some of which optional. Note that it would be more
- // convenient to put the optional trailing object at the end
- // but this would affect children().
- // The trailing objects are in order:
- //
- // * A "Stmt *" for the condition variable.
- // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
- //
- // * A "Stmt *" for the condition.
- // Always present. This is in fact an "Expr *".
- //
- // * A "Stmt *" for the body.
- // Always present.
- //
- enum { VarOffset = 0, BodyOffsetFromCond = 1 };
- enum { NumMandatoryStmtPtr = 2 };
- SourceLocation LParenLoc, RParenLoc;
- unsigned varOffset() const { return VarOffset; }
- unsigned condOffset() const { return VarOffset + hasVarStorage(); }
- unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
- unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
- return NumMandatoryStmtPtr + hasVarStorage();
- }
- /// Build a while statement.
- WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body,
- SourceLocation WL, SourceLocation LParenLoc,
- SourceLocation RParenLoc);
- /// Build an empty while statement.
- explicit WhileStmt(EmptyShell Empty, bool HasVar);
- public:
- /// Create a while statement.
- static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
- Stmt *Body, SourceLocation WL,
- SourceLocation LParenLoc, SourceLocation RParenLoc);
- /// Create an empty while statement optionally with storage for
- /// a condition variable.
- static WhileStmt *CreateEmpty(const ASTContext &Ctx, bool HasVar);
- /// True if this WhileStmt has storage for a condition variable.
- bool hasVarStorage() const { return WhileStmtBits.HasVar; }
- Expr *getCond() {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
- }
- const Expr *getCond() const {
- return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
- }
- void setCond(Expr *Cond) {
- getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
- }
- Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
- const Stmt *getBody() const {
- return getTrailingObjects<Stmt *>()[bodyOffset()];
- }
- void setBody(Stmt *Body) {
- getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
- }
- /// Retrieve the variable declared in this "while" statement, if any.
- ///
- /// In the following example, "x" is the condition variable.
- /// \code
- /// while (int x = random()) {
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable();
- const VarDecl *getConditionVariable() const {
- return const_cast<WhileStmt *>(this)->getConditionVariable();
- }
- /// Set the condition variable of this while statement.
- /// The while statement must have storage for it.
- void setConditionVariable(const ASTContext &Ctx, VarDecl *V);
- /// If this WhileStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- DeclStmt *getConditionVariableDeclStmt() {
- return hasVarStorage() ? static_cast<DeclStmt *>(
- getTrailingObjects<Stmt *>()[varOffset()])
- : nullptr;
- }
- const DeclStmt *getConditionVariableDeclStmt() const {
- return hasVarStorage() ? static_cast<DeclStmt *>(
- getTrailingObjects<Stmt *>()[varOffset()])
- : nullptr;
- }
- SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
- void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getBeginLoc() const { return getWhileLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return getBody()->getEndLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == WhileStmtClass;
- }
- // Iterators
- child_range children() {
- return child_range(getTrailingObjects<Stmt *>(),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- const_child_range children() const {
- return const_child_range(getTrailingObjects<Stmt *>(),
- getTrailingObjects<Stmt *>() +
- numTrailingObjects(OverloadToken<Stmt *>()));
- }
- };
- /// DoStmt - This represents a 'do/while' stmt.
- class DoStmt : public Stmt {
- enum { BODY, COND, END_EXPR };
- Stmt *SubExprs[END_EXPR];
- SourceLocation WhileLoc;
- SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
- public:
- DoStmt(Stmt *Body, Expr *Cond, SourceLocation DL, SourceLocation WL,
- SourceLocation RP)
- : Stmt(DoStmtClass), WhileLoc(WL), RParenLoc(RP) {
- setCond(Cond);
- setBody(Body);
- setDoLoc(DL);
- }
- /// Build an empty do-while statement.
- explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) {}
- Expr *getCond() { return reinterpret_cast<Expr *>(SubExprs[COND]); }
- const Expr *getCond() const {
- return reinterpret_cast<Expr *>(SubExprs[COND]);
- }
- void setCond(Expr *Cond) { SubExprs[COND] = reinterpret_cast<Stmt *>(Cond); }
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getBody() const { return SubExprs[BODY]; }
- void setBody(Stmt *Body) { SubExprs[BODY] = Body; }
- SourceLocation getDoLoc() const { return DoStmtBits.DoLoc; }
- void setDoLoc(SourceLocation L) { DoStmtBits.DoLoc = L; }
- SourceLocation getWhileLoc() const { return WhileLoc; }
- void setWhileLoc(SourceLocation L) { WhileLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getBeginLoc() const { return getDoLoc(); }
- SourceLocation getEndLoc() const { return getRParenLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DoStmtClass;
- }
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
- }
- const_child_range children() const {
- return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
- }
- };
- /// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
- /// the init/cond/inc parts of the ForStmt will be null if they were not
- /// specified in the source.
- class ForStmt : public Stmt {
- enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
- Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
- SourceLocation LParenLoc, RParenLoc;
- public:
- ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
- Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
- SourceLocation RP);
- /// Build an empty for statement.
- explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) {}
- Stmt *getInit() { return SubExprs[INIT]; }
- /// Retrieve the variable declared in this "for" statement, if any.
- ///
- /// In the following example, "y" is the condition variable.
- /// \code
- /// for (int x = random(); int y = mangle(x); ++x) {
- /// // ...
- /// }
- /// \endcode
- VarDecl *getConditionVariable() const;
- void setConditionVariable(const ASTContext &C, VarDecl *V);
- /// If this ForStmt has a condition variable, return the faux DeclStmt
- /// associated with the creation of that condition variable.
- const DeclStmt *getConditionVariableDeclStmt() const {
- return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
- }
- Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
- Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- Stmt *getBody() { return SubExprs[BODY]; }
- const Stmt *getInit() const { return SubExprs[INIT]; }
- const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
- const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
- const Stmt *getBody() const { return SubExprs[BODY]; }
- void setInit(Stmt *S) { SubExprs[INIT] = S; }
- void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
- void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
- void setBody(Stmt *S) { SubExprs[BODY] = S; }
- SourceLocation getForLoc() const { return ForStmtBits.ForLoc; }
- void setForLoc(SourceLocation L) { ForStmtBits.ForLoc = L; }
- SourceLocation getLParenLoc() const { return LParenLoc; }
- void setLParenLoc(SourceLocation L) { LParenLoc = L; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceLocation getBeginLoc() const { return getForLoc(); }
- SourceLocation getEndLoc() const { return getBody()->getEndLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ForStmtClass;
- }
- // Iterators
- child_range children() {
- return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
- }
- const_child_range children() const {
- return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
- }
- };
- /// GotoStmt - This represents a direct goto.
- class GotoStmt : public Stmt {
- LabelDecl *Label;
- SourceLocation LabelLoc;
- public:
- GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
- : Stmt(GotoStmtClass), Label(label), LabelLoc(LL) {
- setGotoLoc(GL);
- }
- /// Build an empty goto statement.
- explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) {}
- LabelDecl *getLabel() const { return Label; }
- void setLabel(LabelDecl *D) { Label = D; }
- SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
- void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
- SourceLocation getLabelLoc() const { return LabelLoc; }
- void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceLocation getBeginLoc() const { return getGotoLoc(); }
- SourceLocation getEndLoc() const { return getLabelLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GotoStmtClass;
- }
- // 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());
- }
- };
- /// IndirectGotoStmt - This represents an indirect goto.
- class IndirectGotoStmt : public Stmt {
- SourceLocation StarLoc;
- Stmt *Target;
- public:
- IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, Expr *target)
- : Stmt(IndirectGotoStmtClass), StarLoc(starLoc) {
- setTarget(target);
- setGotoLoc(gotoLoc);
- }
- /// Build an empty indirect goto statement.
- explicit IndirectGotoStmt(EmptyShell Empty)
- : Stmt(IndirectGotoStmtClass, Empty) {}
- void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
- SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
- void setStarLoc(SourceLocation L) { StarLoc = L; }
- SourceLocation getStarLoc() const { return StarLoc; }
- Expr *getTarget() { return reinterpret_cast<Expr *>(Target); }
- const Expr *getTarget() const {
- return reinterpret_cast<const Expr *>(Target);
- }
- void setTarget(Expr *E) { Target = reinterpret_cast<Stmt *>(E); }
- /// getConstantTarget - Returns the fixed target of this indirect
- /// goto, if one exists.
- LabelDecl *getConstantTarget();
- const LabelDecl *getConstantTarget() const {
- return const_cast<IndirectGotoStmt *>(this)->getConstantTarget();
- }
- SourceLocation getBeginLoc() const { return getGotoLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY { return Target->getEndLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == IndirectGotoStmtClass;
- }
- // Iterators
- child_range children() { return child_range(&Target, &Target + 1); }
- const_child_range children() const {
- return const_child_range(&Target, &Target + 1);
- }
- };
- /// ContinueStmt - This represents a continue.
- class ContinueStmt : public Stmt {
- public:
- ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass) {
- setContinueLoc(CL);
- }
- /// Build an empty continue statement.
- explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}
- SourceLocation getContinueLoc() const { return ContinueStmtBits.ContinueLoc; }
- void setContinueLoc(SourceLocation L) { ContinueStmtBits.ContinueLoc = L; }
- SourceLocation getBeginLoc() const { return getContinueLoc(); }
- SourceLocation getEndLoc() const { return getContinueLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ContinueStmtClass;
- }
- // 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());
- }
- };
- /// BreakStmt - This represents a break.
- class BreakStmt : public Stmt {
- public:
- BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass) {
- setBreakLoc(BL);
- }
- /// Build an empty break statement.
- explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}
- SourceLocation getBreakLoc() const { return BreakStmtBits.BreakLoc; }
- void setBreakLoc(SourceLocation L) { BreakStmtBits.BreakLoc = L; }
- SourceLocation getBeginLoc() const { return getBreakLoc(); }
- SourceLocation getEndLoc() const { return getBreakLoc(); }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BreakStmtClass;
- }
- // 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());
- }
- };
- /// ReturnStmt - This represents a return, optionally of an expression:
- /// return;
- /// return 4;
- ///
- /// Note that GCC allows return with no argument in a function declared to
- /// return a value, and it allows returning a value in functions declared to
- /// return void. We explicitly model this in the AST, which means you can't
- /// depend on the return type of the function and the presence of an argument.
- class ReturnStmt final
- : public Stmt,
- private llvm::TrailingObjects<ReturnStmt, const VarDecl *> {
- friend TrailingObjects;
- /// The return expression.
- Stmt *RetExpr;
- // ReturnStmt is followed optionally by a trailing "const VarDecl *"
- // for the NRVO candidate. Present if and only if hasNRVOCandidate().
- /// True if this ReturnStmt has storage for an NRVO candidate.
- bool hasNRVOCandidate() const { return ReturnStmtBits.HasNRVOCandidate; }
- unsigned numTrailingObjects(OverloadToken<const VarDecl *>) const {
- return hasNRVOCandidate();
- }
- /// Build a return statement.
- ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate);
- /// Build an empty return statement.
- explicit ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate);
- public:
- /// Create a return statement.
- static ReturnStmt *Create(const ASTContext &Ctx, SourceLocation RL, Expr *E,
- const VarDecl *NRVOCandidate);
- /// Create an empty return statement, optionally with
- /// storage for an NRVO candidate.
- static ReturnStmt *CreateEmpty(const ASTContext &Ctx, bool HasNRVOCandidate);
- Expr *getRetValue() { return reinterpret_cast<Expr *>(RetExpr); }
- const Expr *getRetValue() const { return reinterpret_cast<Expr *>(RetExpr); }
- void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt *>(E); }
- /// Retrieve the variable that might be used for the named return
- /// value optimization.
- ///
- /// The optimization itself can only be performed if the variable is
- /// also marked as an NRVO object.
- const VarDecl *getNRVOCandidate() const {
- return hasNRVOCandidate() ? *getTrailingObjects<const VarDecl *>()
- : nullptr;
- }
- /// Set the variable that might be used for the named return value
- /// optimization. The return statement must have storage for it,
- /// which is the case if and only if hasNRVOCandidate() is true.
- void setNRVOCandidate(const VarDecl *Var) {
- assert(hasNRVOCandidate() &&
- "This return statement has no storage for an NRVO candidate!");
- *getTrailingObjects<const VarDecl *>() = Var;
- }
- SourceLocation getReturnLoc() const { return ReturnStmtBits.RetLoc; }
- void setReturnLoc(SourceLocation L) { ReturnStmtBits.RetLoc = L; }
- SourceLocation getBeginLoc() const { return getReturnLoc(); }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return RetExpr ? RetExpr->getEndLoc() : getReturnLoc();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == ReturnStmtClass;
- }
- // Iterators
- child_range children() {
- if (RetExpr)
- return child_range(&RetExpr, &RetExpr + 1);
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range children() const {
- if (RetExpr)
- return const_child_range(&RetExpr, &RetExpr + 1);
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
- };
- /// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
- class AsmStmt : public Stmt {
- protected:
- friend class ASTStmtReader;
- SourceLocation AsmLoc;
- /// True if the assembly statement does not have any input or output
- /// operands.
- bool IsSimple;
- /// If true, treat this inline assembly as having side effects.
- /// This assembly statement should not be optimized, deleted or moved.
- bool IsVolatile;
- unsigned NumOutputs;
- unsigned NumInputs;
- unsigned NumClobbers;
- Stmt **Exprs = nullptr;
- AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
- unsigned numoutputs, unsigned numinputs, unsigned numclobbers)
- : Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
- NumOutputs(numoutputs), NumInputs(numinputs),
- NumClobbers(numclobbers) {}
- public:
- /// Build an empty inline-assembly statement.
- explicit AsmStmt(StmtClass SC, EmptyShell Empty) : Stmt(SC, Empty) {}
- SourceLocation getAsmLoc() const { return AsmLoc; }
- void setAsmLoc(SourceLocation L) { AsmLoc = L; }
- bool isSimple() const { return IsSimple; }
- void setSimple(bool V) { IsSimple = V; }
- bool isVolatile() const { return IsVolatile; }
- void setVolatile(bool V) { IsVolatile = V; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return {}; }
- SourceLocation getEndLoc() const LLVM_READONLY { return {}; }
- //===--- Asm String Analysis ---===//
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
- //===--- Output operands ---===//
- unsigned getNumOutputs() const { return NumOutputs; }
- /// getOutputConstraint - Return the constraint string for the specified
- /// output operand. All output constraints are known to be non-empty (either
- /// '=' or '+').
- StringRef getOutputConstraint(unsigned i) const;
- /// isOutputPlusConstraint - Return true if the specified output constraint
- /// is a "+" constraint (which is both an input and an output) or false if it
- /// is an "=" constraint (just an output).
- bool isOutputPlusConstraint(unsigned i) const {
- return getOutputConstraint(i)[0] == '+';
- }
- const Expr *getOutputExpr(unsigned i) const;
- /// getNumPlusOperands - Return the number of output operands that have a "+"
- /// constraint.
- unsigned getNumPlusOperands() const;
- //===--- Input operands ---===//
- unsigned getNumInputs() const { return NumInputs; }
- /// getInputConstraint - Return the specified input constraint. Unlike output
- /// constraints, these can be empty.
- StringRef getInputConstraint(unsigned i) const;
- const Expr *getInputExpr(unsigned i) const;
- //===--- Other ---===//
- unsigned getNumClobbers() const { return NumClobbers; }
- StringRef getClobber(unsigned i) const;
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GCCAsmStmtClass ||
- T->getStmtClass() == MSAsmStmtClass;
- }
- // Input expr iterators.
- using inputs_iterator = ExprIterator;
- using const_inputs_iterator = ConstExprIterator;
- using inputs_range = llvm::iterator_range<inputs_iterator>;
- using inputs_const_range = llvm::iterator_range<const_inputs_iterator>;
- inputs_iterator begin_inputs() {
- return &Exprs[0] + NumOutputs;
- }
- inputs_iterator end_inputs() {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
- inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
- const_inputs_iterator begin_inputs() const {
- return &Exprs[0] + NumOutputs;
- }
- const_inputs_iterator end_inputs() const {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
- inputs_const_range inputs() const {
- return inputs_const_range(begin_inputs(), end_inputs());
- }
- // Output expr iterators.
- using outputs_iterator = ExprIterator;
- using const_outputs_iterator = ConstExprIterator;
- using outputs_range = llvm::iterator_range<outputs_iterator>;
- using outputs_const_range = llvm::iterator_range<const_outputs_iterator>;
- outputs_iterator begin_outputs() {
- return &Exprs[0];
- }
- outputs_iterator end_outputs() {
- return &Exprs[0] + NumOutputs;
- }
- outputs_range outputs() {
- return outputs_range(begin_outputs(), end_outputs());
- }
- const_outputs_iterator begin_outputs() const {
- return &Exprs[0];
- }
- const_outputs_iterator end_outputs() const {
- return &Exprs[0] + NumOutputs;
- }
- outputs_const_range outputs() const {
- return outputs_const_range(begin_outputs(), end_outputs());
- }
- child_range children() {
- return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
- }
- const_child_range children() const {
- return const_child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
- }
- };
- /// This represents a GCC inline-assembly statement extension.
- class GCCAsmStmt : public AsmStmt {
- friend class ASTStmtReader;
- SourceLocation RParenLoc;
- StringLiteral *AsmStr;
- // FIXME: If we wanted to, we could allocate all of these in one big array.
- StringLiteral **Constraints = nullptr;
- StringLiteral **Clobbers = nullptr;
- IdentifierInfo **Names = nullptr;
- unsigned NumLabels = 0;
- public:
- GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
- bool isvolatile, unsigned numoutputs, unsigned numinputs,
- IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
- StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, unsigned numlabels,
- SourceLocation rparenloc);
- /// Build an empty inline-assembly statement.
- explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
- SourceLocation getRParenLoc() const { return RParenLoc; }
- void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- //===--- Asm String Analysis ---===//
- const StringLiteral *getAsmString() const { return AsmStr; }
- StringLiteral *getAsmString() { return AsmStr; }
- void setAsmString(StringLiteral *E) { AsmStr = E; }
- /// AsmStringPiece - this is part of a decomposed asm string specification
- /// (for use with the AnalyzeAsmString function below). An asm string is
- /// considered to be a concatenation of these parts.
- class AsmStringPiece {
- public:
- enum Kind {
- String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
- Operand // Operand reference, with optional modifier %c4.
- };
- private:
- Kind MyKind;
- std::string Str;
- unsigned OperandNo;
- // Source range for operand references.
- CharSourceRange Range;
- public:
- AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
- AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
- SourceLocation End)
- : MyKind(Operand), Str(S), OperandNo(OpNo),
- Range(CharSourceRange::getCharRange(Begin, End)) {}
- bool isString() const { return MyKind == String; }
- bool isOperand() const { return MyKind == Operand; }
- const std::string &getString() const { return Str; }
- unsigned getOperandNo() const {
- assert(isOperand());
- return OperandNo;
- }
- CharSourceRange getRange() const {
- assert(isOperand() && "Range is currently used only for Operands.");
- return Range;
- }
- /// getModifier - Get the modifier for this operand, if present. This
- /// returns '\0' if there was no modifier.
- char getModifier() const;
- };
- /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
- /// it into pieces. If the asm string is erroneous, emit errors and return
- /// true, otherwise return false. This handles canonicalization and
- /// translation of strings from GCC syntax to LLVM IR syntax, and handles
- //// flattening of named references like %[foo] to Operand AsmStringPiece's.
- unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
- const ASTContext &C, unsigned &DiagOffs) const;
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
- //===--- Output operands ---===//
- IdentifierInfo *getOutputIdentifier(unsigned i) const { return Names[i]; }
- StringRef getOutputName(unsigned i) const {
- if (IdentifierInfo *II = getOutputIdentifier(i))
- return II->getName();
- return {};
- }
- StringRef getOutputConstraint(unsigned i) const;
- const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
- return Constraints[i];
- }
- StringLiteral *getOutputConstraintLiteral(unsigned i) {
- return Constraints[i];
- }
- Expr *getOutputExpr(unsigned i);
- const Expr *getOutputExpr(unsigned i) const {
- return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
- }
- //===--- Input operands ---===//
- IdentifierInfo *getInputIdentifier(unsigned i) const {
- return Names[i + NumOutputs];
- }
- StringRef getInputName(unsigned i) const {
- if (IdentifierInfo *II = getInputIdentifier(i))
- return II->getName();
- return {};
- }
- StringRef getInputConstraint(unsigned i) const;
- const StringLiteral *getInputConstraintLiteral(unsigned i) const {
- return Constraints[i + NumOutputs];
- }
- StringLiteral *getInputConstraintLiteral(unsigned i) {
- return Constraints[i + NumOutputs];
- }
- Expr *getInputExpr(unsigned i);
- void setInputExpr(unsigned i, Expr *E);
- const Expr *getInputExpr(unsigned i) const {
- return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
- }
- //===--- Labels ---===//
- bool isAsmGoto() const {
- return NumLabels > 0;
- }
- unsigned getNumLabels() const {
- return NumLabels;
- }
- IdentifierInfo *getLabelIdentifier(unsigned i) const {
- return Names[i + NumOutputs + NumInputs];
- }
- AddrLabelExpr *getLabelExpr(unsigned i) const;
- StringRef getLabelName(unsigned i) const;
- using labels_iterator = CastIterator<AddrLabelExpr>;
- using const_labels_iterator = ConstCastIterator<AddrLabelExpr>;
- using labels_range = llvm::iterator_range<labels_iterator>;
- using labels_const_range = llvm::iterator_range<const_labels_iterator>;
- labels_iterator begin_labels() {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
- labels_iterator end_labels() {
- return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
- }
- labels_range labels() {
- return labels_range(begin_labels(), end_labels());
- }
- const_labels_iterator begin_labels() const {
- return &Exprs[0] + NumOutputs + NumInputs;
- }
- const_labels_iterator end_labels() const {
- return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
- }
- labels_const_range labels() const {
- return labels_const_range(begin_labels(), end_labels());
- }
- private:
- void setOutputsAndInputsAndClobbers(const ASTContext &C,
- IdentifierInfo **Names,
- StringLiteral **Constraints,
- Stmt **Exprs,
- unsigned NumOutputs,
- unsigned NumInputs,
- unsigned NumLabels,
- StringLiteral **Clobbers,
- unsigned NumClobbers);
- public:
- //===--- Other ---===//
- /// getNamedOperand - Given a symbolic operand reference like %[foo],
- /// translate this into a numeric value needed to reference the same operand.
- /// This returns -1 if the operand name is invalid.
- int getNamedOperand(StringRef SymbolicName) const;
- StringRef getClobber(unsigned i) const;
- StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
- const StringLiteral *getClobberStringLiteral(unsigned i) const {
- return Clobbers[i];
- }
- SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == GCCAsmStmtClass;
- }
- };
- /// This represents a Microsoft inline-assembly statement extension.
- class MSAsmStmt : public AsmStmt {
- friend class ASTStmtReader;
- SourceLocation LBraceLoc, EndLoc;
- StringRef AsmStr;
- unsigned NumAsmToks = 0;
- Token *AsmToks = nullptr;
- StringRef *Constraints = nullptr;
- StringRef *Clobbers = nullptr;
- public:
- MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
- SourceLocation lbraceloc, bool issimple, bool isvolatile,
- ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
- ArrayRef<StringRef> constraints,
- ArrayRef<Expr*> exprs, StringRef asmstr,
- ArrayRef<StringRef> clobbers, SourceLocation endloc);
- /// Build an empty MS-style inline-assembly statement.
- explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty) {}
- SourceLocation getLBraceLoc() const { return LBraceLoc; }
- void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
- SourceLocation getEndLoc() const { return EndLoc; }
- void setEndLoc(SourceLocation L) { EndLoc = L; }
- bool hasBraces() const { return LBraceLoc.isValid(); }
- unsigned getNumAsmToks() { return NumAsmToks; }
- Token *getAsmToks() { return AsmToks; }
- //===--- Asm String Analysis ---===//
- StringRef getAsmString() const { return AsmStr; }
- /// Assemble final IR asm string.
- std::string generateAsmString(const ASTContext &C) const;
- //===--- Output operands ---===//
- StringRef getOutputConstraint(unsigned i) const {
- assert(i < NumOutputs);
- return Constraints[i];
- }
- Expr *getOutputExpr(unsigned i);
- const Expr *getOutputExpr(unsigned i) const {
- return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
- }
- //===--- Input operands ---===//
- StringRef getInputConstraint(unsigned i) const {
- assert(i < NumInputs);
- return Constraints[i + NumOutputs];
- }
- Expr *getInputExpr(unsigned i);
- void setInputExpr(unsigned i, Expr *E);
- const Expr *getInputExpr(unsigned i) const {
- return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
- }
- //===--- Other ---===//
- ArrayRef<StringRef> getAllConstraints() const {
- return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
- }
- ArrayRef<StringRef> getClobbers() const {
- return llvm::makeArrayRef(Clobbers, NumClobbers);
- }
- ArrayRef<Expr*> getAllExprs() const {
- return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
- NumInputs + NumOutputs);
- }
- StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
- private:
- void initialize(const ASTContext &C, StringRef AsmString,
- ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
- ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
- public:
- SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == MSAsmStmtClass;
- }
- child_range children() {
- return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
- }
- const_child_range children() const {
- return const_child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
- }
- };
- class SEHExceptStmt : public Stmt {
- friend class ASTReader;
- friend class ASTStmtReader;
- SourceLocation Loc;
- Stmt *Children[2];
- enum { FILTER_EXPR, BLOCK };
- SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block);
- explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) {}
- public:
- static SEHExceptStmt* Create(const ASTContext &C,
- SourceLocation ExceptLoc,
- Expr *FilterExpr,
- Stmt *Block);
- SourceLocation getBeginLoc() const LLVM_READONLY { return getExceptLoc(); }
- SourceLocation getExceptLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return getBlock()->getEndLoc(); }
- Expr *getFilterExpr() const {
- return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
- }
- CompoundStmt *getBlock() const {
- return cast<CompoundStmt>(Children[BLOCK]);
- }
- child_range children() {
- return child_range(Children, Children+2);
- }
- const_child_range children() const {
- return const_child_range(Children, Children + 2);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHExceptStmtClass;
- }
- };
- class SEHFinallyStmt : public Stmt {
- friend class ASTReader;
- friend class ASTStmtReader;
- SourceLocation Loc;
- Stmt *Block;
- SEHFinallyStmt(SourceLocation Loc, Stmt *Block);
- explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) {}
- public:
- static SEHFinallyStmt* Create(const ASTContext &C,
- SourceLocation FinallyLoc,
- Stmt *Block);
- SourceLocation getBeginLoc() const LLVM_READONLY { return getFinallyLoc(); }
- SourceLocation getFinallyLoc() const { return Loc; }
- SourceLocation getEndLoc() const { return Block->getEndLoc(); }
- CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
- child_range children() {
- return child_range(&Block,&Block+1);
- }
- const_child_range children() const {
- return const_child_range(&Block, &Block + 1);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHFinallyStmtClass;
- }
- };
- class SEHTryStmt : public Stmt {
- friend class ASTReader;
- friend class ASTStmtReader;
- bool IsCXXTry;
- SourceLocation TryLoc;
- Stmt *Children[2];
- enum { TRY = 0, HANDLER = 1 };
- SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
- SourceLocation TryLoc,
- Stmt *TryBlock,
- Stmt *Handler);
- explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) {}
- public:
- static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
- SourceLocation TryLoc, Stmt *TryBlock,
- Stmt *Handler);
- SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }
- SourceLocation getTryLoc() const { return TryLoc; }
- SourceLocation getEndLoc() const { return Children[HANDLER]->getEndLoc(); }
- bool getIsCXXTry() const { return IsCXXTry; }
- CompoundStmt* getTryBlock() const {
- return cast<CompoundStmt>(Children[TRY]);
- }
- Stmt *getHandler() const { return Children[HANDLER]; }
- /// Returns 0 if not defined
- SEHExceptStmt *getExceptHandler() const;
- SEHFinallyStmt *getFinallyHandler() const;
- child_range children() {
- return child_range(Children, Children+2);
- }
- const_child_range children() const {
- return const_child_range(Children, Children + 2);
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHTryStmtClass;
- }
- };
- /// Represents a __leave statement.
- class SEHLeaveStmt : public Stmt {
- SourceLocation LeaveLoc;
- public:
- explicit SEHLeaveStmt(SourceLocation LL)
- : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
- /// Build an empty __leave statement.
- explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) {}
- SourceLocation getLeaveLoc() const { return LeaveLoc; }
- void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return LeaveLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return LeaveLoc; }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == SEHLeaveStmtClass;
- }
- // 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());
- }
- };
- /// This captures a statement into a function. For example, the following
- /// pragma annotated compound statement can be represented as a CapturedStmt,
- /// and this compound statement is the body of an anonymous outlined function.
- /// @code
- /// #pragma omp parallel
- /// {
- /// compute();
- /// }
- /// @endcode
- class CapturedStmt : public Stmt {
- public:
- /// The different capture forms: by 'this', by reference, capture for
- /// variable-length array type etc.
- enum VariableCaptureKind {
- VCK_This,
- VCK_ByRef,
- VCK_ByCopy,
- VCK_VLAType,
- };
- /// Describes the capture of either a variable, or 'this', or
- /// variable-length array type.
- class Capture {
- llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
- SourceLocation Loc;
- public:
- friend class ASTStmtReader;
- /// Create a new capture.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, ByRef, ...).
- ///
- /// \param Var The variable being captured, or null if capturing this.
- Capture(SourceLocation Loc, VariableCaptureKind Kind,
- VarDecl *Var = nullptr);
- /// Determine the kind of capture.
- VariableCaptureKind getCaptureKind() const;
- /// Retrieve the source location at which the variable or 'this' was
- /// first used.
- SourceLocation getLocation() const { return Loc; }
- /// Determine whether this capture handles the C++ 'this' pointer.
- bool capturesThis() const { return getCaptureKind() == VCK_This; }
- /// Determine whether this capture handles a variable (by reference).
- bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }
- /// Determine whether this capture handles a variable by copy.
- bool capturesVariableByCopy() const {
- return getCaptureKind() == VCK_ByCopy;
- }
- /// Determine whether this capture handles a variable-length array
- /// type.
- bool capturesVariableArrayType() const {
- return getCaptureKind() == VCK_VLAType;
- }
- /// Retrieve the declaration of the variable being captured.
- ///
- /// This operation is only valid if this capture captures a variable.
- VarDecl *getCapturedVar() const;
- };
- private:
- /// The number of variable captured, including 'this'.
- unsigned NumCaptures;
- /// The pointer part is the implicit the outlined function and the
- /// int part is the captured region kind, 'CR_Default' etc.
- llvm::PointerIntPair<CapturedDecl *, 2, CapturedRegionKind> CapDeclAndKind;
- /// The record for captured variables, a RecordDecl or CXXRecordDecl.
- RecordDecl *TheRecordDecl = nullptr;
- /// Construct a captured statement.
- CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
- ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
- /// Construct an empty captured statement.
- CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
- Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); }
- Stmt *const *getStoredStmts() const {
- return reinterpret_cast<Stmt *const *>(this + 1);
- }
- Capture *getStoredCaptures() const;
- void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
- public:
- friend class ASTStmtReader;
- static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
- CapturedRegionKind Kind,
- ArrayRef<Capture> Captures,
- ArrayRef<Expr *> CaptureInits,
- CapturedDecl *CD, RecordDecl *RD);
- static CapturedStmt *CreateDeserialized(const ASTContext &Context,
- unsigned NumCaptures);
- /// Retrieve the statement being captured.
- Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
- const Stmt *getCapturedStmt() const { return getStoredStmts()[NumCaptures]; }
- /// Retrieve the outlined function declaration.
- CapturedDecl *getCapturedDecl();
- const CapturedDecl *getCapturedDecl() const;
- /// Set the outlined function declaration.
- void setCapturedDecl(CapturedDecl *D);
- /// Retrieve the captured region kind.
- CapturedRegionKind getCapturedRegionKind() const;
- /// Set the captured region kind.
- void setCapturedRegionKind(CapturedRegionKind Kind);
- /// Retrieve the record declaration for captured variables.
- const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
- /// Set the record declaration for captured variables.
- void setCapturedRecordDecl(RecordDecl *D) {
- assert(D && "null RecordDecl");
- TheRecordDecl = D;
- }
- /// True if this variable has been captured.
- bool capturesVariable(const VarDecl *Var) const;
- /// An iterator that walks over the captures.
- using capture_iterator = Capture *;
- using const_capture_iterator = const Capture *;
- using capture_range = llvm::iterator_range<capture_iterator>;
- using capture_const_range = llvm::iterator_range<const_capture_iterator>;
- capture_range captures() {
- return capture_range(capture_begin(), capture_end());
- }
- capture_const_range captures() const {
- return capture_const_range(capture_begin(), capture_end());
- }
- /// Retrieve an iterator pointing to the first capture.
- capture_iterator capture_begin() { return getStoredCaptures(); }
- const_capture_iterator capture_begin() const { return getStoredCaptures(); }
- /// Retrieve an iterator pointing past the end of the sequence of
- /// captures.
- capture_iterator capture_end() const {
- return getStoredCaptures() + NumCaptures;
- }
- /// Retrieve the number of captures, including 'this'.
- unsigned capture_size() const { return NumCaptures; }
- /// Iterator that walks over the capture initialization arguments.
- using capture_init_iterator = Expr **;
- using capture_init_range = llvm::iterator_range<capture_init_iterator>;
- /// Const iterator that walks over the capture initialization
- /// arguments.
- using const_capture_init_iterator = Expr *const *;
- using const_capture_init_range =
- llvm::iterator_range<const_capture_init_iterator>;
- capture_init_range capture_inits() {
- return capture_init_range(capture_init_begin(), capture_init_end());
- }
- const_capture_init_range capture_inits() const {
- return const_capture_init_range(capture_init_begin(), capture_init_end());
- }
- /// Retrieve the first initialization argument.
- capture_init_iterator capture_init_begin() {
- return reinterpret_cast<Expr **>(getStoredStmts());
- }
- const_capture_init_iterator capture_init_begin() const {
- return reinterpret_cast<Expr *const *>(getStoredStmts());
- }
- /// Retrieve the iterator pointing one past the last initialization
- /// argument.
- capture_init_iterator capture_init_end() {
- return capture_init_begin() + NumCaptures;
- }
- const_capture_init_iterator capture_init_end() const {
- return capture_init_begin() + NumCaptures;
- }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- return getCapturedStmt()->getBeginLoc();
- }
- SourceLocation getEndLoc() const LLVM_READONLY {
- return getCapturedStmt()->getEndLoc();
- }
- SourceRange getSourceRange() const LLVM_READONLY {
- return getCapturedStmt()->getSourceRange();
- }
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == CapturedStmtClass;
- }
- child_range children();
- const_child_range children() const;
- };
- } // namespace clang
- #endif // LLVM_CLANG_AST_STMT_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|