12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- 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 RecursiveASTVisitor interface, which recursively
- // traverses the entire AST.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
- #define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
- #include "clang/AST/ASTConcept.h"
- #include "clang/AST/Attr.h"
- #include "clang/AST/Decl.h"
- #include "clang/AST/DeclBase.h"
- #include "clang/AST/DeclCXX.h"
- #include "clang/AST/DeclFriend.h"
- #include "clang/AST/DeclObjC.h"
- #include "clang/AST/DeclOpenMP.h"
- #include "clang/AST/DeclTemplate.h"
- #include "clang/AST/DeclarationName.h"
- #include "clang/AST/Expr.h"
- #include "clang/AST/ExprCXX.h"
- #include "clang/AST/ExprConcepts.h"
- #include "clang/AST/ExprObjC.h"
- #include "clang/AST/ExprOpenMP.h"
- #include "clang/AST/LambdaCapture.h"
- #include "clang/AST/NestedNameSpecifier.h"
- #include "clang/AST/OpenMPClause.h"
- #include "clang/AST/Stmt.h"
- #include "clang/AST/StmtCXX.h"
- #include "clang/AST/StmtObjC.h"
- #include "clang/AST/StmtOpenMP.h"
- #include "clang/AST/TemplateBase.h"
- #include "clang/AST/TemplateName.h"
- #include "clang/AST/Type.h"
- #include "clang/AST/TypeLoc.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/Basic/OpenMPKinds.h"
- #include "clang/Basic/Specifiers.h"
- #include "llvm/ADT/PointerIntPair.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/Support/Casting.h"
- #include <algorithm>
- #include <cstddef>
- #include <type_traits>
- namespace clang {
- // A helper macro to implement short-circuiting when recursing. It
- // invokes CALL_EXPR, which must be a method call, on the derived
- // object (s.t. a user of RecursiveASTVisitor can override the method
- // in CALL_EXPR).
- #define TRY_TO(CALL_EXPR) \
- do { \
- if (!getDerived().CALL_EXPR) \
- return false; \
- } while (false)
- namespace detail {
- template <typename T, typename U>
- struct has_same_member_pointer_type : std::false_type {};
- template <typename T, typename U, typename R, typename... P>
- struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
- : std::true_type {};
- /// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
- /// are pointers to the same non-static member function.
- template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
- LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto
- isSameMethod([[maybe_unused]] FirstMethodPtrTy FirstMethodPtr,
- [[maybe_unused]] SecondMethodPtrTy SecondMethodPtr)
- -> bool {
- if constexpr (has_same_member_pointer_type<FirstMethodPtrTy,
- SecondMethodPtrTy>::value)
- return FirstMethodPtr == SecondMethodPtr;
- return false;
- }
- } // end namespace detail
- /// A class that does preorder or postorder
- /// depth-first traversal on the entire Clang AST and visits each node.
- ///
- /// This class performs three distinct tasks:
- /// 1. traverse the AST (i.e. go to each node);
- /// 2. at a given node, walk up the class hierarchy, starting from
- /// the node's dynamic type, until the top-most class (e.g. Stmt,
- /// Decl, or Type) is reached.
- /// 3. given a (node, class) combination, where 'class' is some base
- /// class of the dynamic type of 'node', call a user-overridable
- /// function to actually visit the node.
- ///
- /// These tasks are done by three groups of methods, respectively:
- /// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
- /// for traversing an AST rooted at x. This method simply
- /// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
- /// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
- /// then recursively visits the child nodes of x.
- /// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
- /// similarly.
- /// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
- /// any child node of x. Instead, it first calls WalkUpFromBar(x)
- /// where Bar is the direct parent class of Foo (unless Foo has
- /// no parent), and then calls VisitFoo(x) (see the next list item).
- /// 3. VisitFoo(Foo *x) does task #3.
- ///
- /// These three method groups are tiered (Traverse* > WalkUpFrom* >
- /// Visit*). A method (e.g. Traverse*) may call methods from the same
- /// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
- /// It may not call methods from a higher tier.
- ///
- /// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
- /// is Foo's super class) before calling VisitFoo(), the result is
- /// that the Visit*() methods for a given node are called in the
- /// top-down order (e.g. for a node of type NamespaceDecl, the order will
- /// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
- ///
- /// This scheme guarantees that all Visit*() calls for the same AST
- /// node are grouped together. In other words, Visit*() methods for
- /// different nodes are never interleaved.
- ///
- /// Clients of this visitor should subclass the visitor (providing
- /// themselves as the template argument, using the curiously recurring
- /// template pattern) and override any of the Traverse*, WalkUpFrom*,
- /// and Visit* methods for declarations, types, statements,
- /// expressions, or other AST nodes where the visitor should customize
- /// behavior. Most users only need to override Visit*. Advanced
- /// users may override Traverse* and WalkUpFrom* to implement custom
- /// traversal strategies. Returning false from one of these overridden
- /// functions will abort the entire traversal.
- ///
- /// By default, this visitor tries to visit every part of the explicit
- /// source code exactly once. The default policy towards templates
- /// is to descend into the 'pattern' class or function body, not any
- /// explicit or implicit instantiations. Explicit specializations
- /// are still visited, and the patterns of partial specializations
- /// are visited separately. This behavior can be changed by
- /// overriding shouldVisitTemplateInstantiations() in the derived class
- /// to return true, in which case all known implicit and explicit
- /// instantiations will be visited at the same time as the pattern
- /// from which they were produced.
- ///
- /// By default, this visitor preorder traverses the AST. If postorder traversal
- /// is needed, the \c shouldTraversePostOrder method needs to be overridden
- /// to return \c true.
- template <typename Derived> class RecursiveASTVisitor {
- public:
- /// A queue used for performing data recursion over statements.
- /// Parameters involving this type are used to implement data
- /// recursion over Stmts and Exprs within this class, and should
- /// typically not be explicitly specified by derived classes.
- /// The bool bit indicates whether the statement has been traversed or not.
- typedef SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>>
- DataRecursionQueue;
- /// Return a reference to the derived class.
- Derived &getDerived() { return *static_cast<Derived *>(this); }
- /// Return whether this visitor should recurse into
- /// template instantiations.
- bool shouldVisitTemplateInstantiations() const { return false; }
- /// Return whether this visitor should recurse into the types of
- /// TypeLocs.
- bool shouldWalkTypesOfTypeLocs() const { return true; }
- /// Return whether this visitor should recurse into implicit
- /// code, e.g., implicit constructors and destructors.
- bool shouldVisitImplicitCode() const { return false; }
- /// Return whether this visitor should recurse into lambda body
- bool shouldVisitLambdaBody() const { return true; }
- /// Return whether this visitor should traverse post-order.
- bool shouldTraversePostOrder() const { return false; }
- /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
- /// \returns false if visitation was terminated early.
- bool TraverseAST(ASTContext &AST) {
- // Currently just an alias for TraverseDecl(TUDecl), but kept in case
- // we change the implementation again.
- return getDerived().TraverseDecl(AST.getTranslationUnitDecl());
- }
- /// Recursively visit a statement or expression, by
- /// dispatching to Traverse*() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is nullptr).
- bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
- /// Invoked before visiting a statement or expression via data recursion.
- ///
- /// \returns false to skip visiting the node, true otherwise.
- bool dataTraverseStmtPre(Stmt *S) { return true; }
- /// Invoked after visiting a statement or expression via data recursion.
- /// This is not invoked if the previously invoked \c dataTraverseStmtPre
- /// returned false.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool dataTraverseStmtPost(Stmt *S) { return true; }
- /// Recursively visit a type, by dispatching to
- /// Traverse*Type() based on the argument's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type).
- bool TraverseType(QualType T);
- /// Recursively visit a type with location, by dispatching to
- /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type location).
- bool TraverseTypeLoc(TypeLoc TL);
- /// Recursively visit an attribute, by dispatching to
- /// Traverse*Attr() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is a Null type location).
- bool TraverseAttr(Attr *At);
- /// Recursively visit a declaration, by dispatching to
- /// Traverse*Decl() based on the argument's dynamic type.
- ///
- /// \returns false if the visitation was terminated early, true
- /// otherwise (including when the argument is NULL).
- bool TraverseDecl(Decl *D);
- /// Recursively visit a C++ nested-name-specifier.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
- /// Recursively visit a C++ nested-name-specifier with location
- /// information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
- /// Recursively visit a name with its location information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
- /// Recursively visit a template name and dispatch to the
- /// appropriate method.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateName(TemplateName Template);
- /// Recursively visit a template argument and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: migrate callers to TemplateArgumentLoc instead.
- bool TraverseTemplateArgument(const TemplateArgument &Arg);
- /// Recursively visit a template argument location and dispatch to the
- /// appropriate method for the argument type.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
- /// Recursively visit a set of template arguments.
- /// This can be overridden by a subclass, but it's not expected that
- /// will be needed -- this visitor always dispatches to another.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
- bool TraverseTemplateArguments(ArrayRef<TemplateArgument> Args);
- /// Recursively visit a base specifier. This can be overridden by a
- /// subclass.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base);
- /// Recursively visit a constructor initializer. This
- /// automatically dispatches to another visitor for the initializer
- /// expression, but not for the name of the initializer, so may
- /// be overridden for clients that need access to the name.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
- /// Recursively visit a lambda capture. \c Init is the expression that
- /// will be used to initialize the capture.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
- Expr *Init);
- /// Recursively visit the syntactic or semantic form of an
- /// initialization list.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseSynOrSemInitListExpr(InitListExpr *S,
- DataRecursionQueue *Queue = nullptr);
- /// Recursively visit an Objective-C protocol reference with location
- /// information.
- ///
- /// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
- // ---- Methods on Attrs ----
- // Visit an attribute.
- bool VisitAttr(Attr *A) { return true; }
- // Declare Traverse* and empty Visit* for all Attr classes.
- #define ATTR_VISITOR_DECLS_ONLY
- #include "clang/AST/AttrVisitor.inc"
- #undef ATTR_VISITOR_DECLS_ONLY
- // ---- Methods on Stmts ----
- Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
- private:
- // Traverse the given statement. If the most-derived traverse function takes a
- // data recursion queue, pass it on; otherwise, discard it. Note that the
- // first branch of this conditional must compile whether or not the derived
- // class can take a queue, so if we're taking the second arm, make the first
- // arm call our function rather than the derived class version.
- #define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
- (::clang::detail::has_same_member_pointer_type< \
- decltype(&RecursiveASTVisitor::Traverse##NAME), \
- decltype(&Derived::Traverse##NAME)>::value \
- ? static_cast<std::conditional_t< \
- ::clang::detail::has_same_member_pointer_type< \
- decltype(&RecursiveASTVisitor::Traverse##NAME), \
- decltype(&Derived::Traverse##NAME)>::value, \
- Derived &, RecursiveASTVisitor &>>(*this) \
- .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
- : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
- // Try to traverse the given statement, or enqueue it if we're performing data
- // recursion in the middle of traversing another statement. Can only be called
- // from within a DEF_TRAVERSE_STMT body or similar context.
- #define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \
- do { \
- if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
- return false; \
- } while (false)
- public:
- // Declare Traverse*() for all concrete Stmt classes.
- #define ABSTRACT_STMT(STMT)
- #define STMT(CLASS, PARENT) \
- bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr);
- #include "clang/AST/StmtNodes.inc"
- // The above header #undefs ABSTRACT_STMT and STMT upon exit.
- // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
- bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
- bool VisitStmt(Stmt *S) { return true; }
- #define STMT(CLASS, PARENT) \
- bool WalkUpFrom##CLASS(CLASS *S) { \
- TRY_TO(WalkUpFrom##PARENT(S)); \
- TRY_TO(Visit##CLASS(S)); \
- return true; \
- } \
- bool Visit##CLASS(CLASS *S) { return true; }
- #include "clang/AST/StmtNodes.inc"
- // ---- Methods on Types ----
- // FIXME: revamp to take TypeLoc's rather than Types.
- // Declare Traverse*() for all concrete Type classes.
- #define ABSTRACT_TYPE(CLASS, BASE)
- #define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
- #include "clang/AST/TypeNodes.inc"
- // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
- // Define WalkUpFrom*() and empty Visit*() for all Type classes.
- bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
- bool VisitType(Type *T) { return true; }
- #define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
- TRY_TO(WalkUpFrom##BASE(T)); \
- TRY_TO(Visit##CLASS##Type(T)); \
- return true; \
- } \
- bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
- #include "clang/AST/TypeNodes.inc"
- // ---- Methods on TypeLocs ----
- // FIXME: this currently just calls the matching Type methods
- // Declare Traverse*() for all concrete TypeLoc classes.
- #define ABSTRACT_TYPELOC(CLASS, BASE)
- #define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
- #include "clang/AST/TypeLocNodes.def"
- // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
- // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
- bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
- bool VisitTypeLoc(TypeLoc TL) { return true; }
- // QualifiedTypeLoc and UnqualTypeLoc are not declared in
- // TypeNodes.inc and thus need to be handled specially.
- bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
- bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
- return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
- }
- bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
- // Note that BASE includes trailing 'Type' which CLASS doesn't.
- #define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
- TRY_TO(Visit##CLASS##TypeLoc(TL)); \
- return true; \
- } \
- bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
- #include "clang/AST/TypeNodes.inc"
- // ---- Methods on Decls ----
- // Declare Traverse*() for all concrete Decl classes.
- #define ABSTRACT_DECL(DECL)
- #define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
- #include "clang/AST/DeclNodes.inc"
- // The above header #undefs ABSTRACT_DECL and DECL upon exit.
- // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
- bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
- bool VisitDecl(Decl *D) { return true; }
- #define DECL(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
- TRY_TO(WalkUpFrom##BASE(D)); \
- TRY_TO(Visit##CLASS##Decl(D)); \
- return true; \
- } \
- bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
- #include "clang/AST/DeclNodes.inc"
- bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child);
- #define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
- bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
- DEF_TRAVERSE_TMPL_INST(Class)
- DEF_TRAVERSE_TMPL_INST(Var)
- DEF_TRAVERSE_TMPL_INST(Function)
- #undef DEF_TRAVERSE_TMPL_INST
- bool TraverseTypeConstraint(const TypeConstraint *C);
- bool TraverseConceptRequirement(concepts::Requirement *R);
- bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
- bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
- bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
- bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
- private:
- // These are helper methods used by more than one Traverse* method.
- bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
- /// Traverses the qualifier, name and template arguments of a concept
- /// reference.
- bool TraverseConceptReferenceHelper(const ConceptReference &C);
- // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
- template <typename T>
- bool TraverseDeclTemplateParameterLists(T *D);
- bool TraverseTemplateTypeParamDeclConstraints(const TemplateTypeParmDecl *D);
- bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
- unsigned Count);
- bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
- bool TraverseRecordHelper(RecordDecl *D);
- bool TraverseCXXRecordHelper(CXXRecordDecl *D);
- bool TraverseDeclaratorHelper(DeclaratorDecl *D);
- bool TraverseDeclContextHelper(DeclContext *DC);
- bool TraverseFunctionHelper(FunctionDecl *D);
- bool TraverseVarHelper(VarDecl *D);
- bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
- bool TraverseOMPLoopDirective(OMPLoopDirective *S);
- bool TraverseOMPClause(OMPClause *C);
- #define GEN_CLANG_CLAUSE_CLASS
- #define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
- #include "llvm/Frontend/OpenMP/OMP.inc"
- /// Process clauses with list of variables.
- template <typename T> bool VisitOMPClauseList(T *Node);
- /// Process clauses with pre-initis.
- bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node);
- bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node);
- bool PostVisitStmt(Stmt *S);
- };
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTypeConstraint(
- const TypeConstraint *C) {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO(TraverseConceptReferenceHelper(*C));
- return true;
- }
- if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
- TRY_TO(TraverseStmt(IDC));
- } else {
- // Avoid traversing the ConceptReference in the TypeConstraint
- // if we have an immediately-declared-constraint, otherwise
- // we'll end up visiting the concept and the arguments in
- // the TC twice.
- TRY_TO(TraverseConceptReferenceHelper(*C));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseConceptRequirement(
- concepts::Requirement *R) {
- switch (R->getKind()) {
- case concepts::Requirement::RK_Type:
- return getDerived().TraverseConceptTypeRequirement(
- cast<concepts::TypeRequirement>(R));
- case concepts::Requirement::RK_Simple:
- case concepts::Requirement::RK_Compound:
- return getDerived().TraverseConceptExprRequirement(
- cast<concepts::ExprRequirement>(R));
- case concepts::Requirement::RK_Nested:
- return getDerived().TraverseConceptNestedRequirement(
- cast<concepts::NestedRequirement>(R));
- }
- llvm_unreachable("unexpected case");
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseConceptReferenceHelper(
- const ConceptReference &C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C.getNestedNameSpecifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C.getConceptNameInfo()));
- if (C.hasExplicitTemplateArgs())
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- C.getTemplateArgsAsWritten()->getTemplateArgs(),
- C.getTemplateArgsAsWritten()->NumTemplateArgs));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
- DataRecursionQueue *Queue) {
- // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
- switch (S->getStmtClass()) {
- case Stmt::NoStmtClass:
- break;
- #define ABSTRACT_STMT(STMT)
- #define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: \
- return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue);
- #include "clang/AST/StmtNodes.inc"
- }
- return true;
- }
- #undef DISPATCH_STMT
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseConceptTypeRequirement(
- concepts::TypeRequirement *R) {
- if (R->isSubstitutionFailure())
- return true;
- return getDerived().TraverseTypeLoc(R->getType()->getTypeLoc());
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseConceptExprRequirement(
- concepts::ExprRequirement *R) {
- if (!R->isExprSubstitutionFailure())
- TRY_TO(TraverseStmt(R->getExpr()));
- auto &RetReq = R->getReturnTypeRequirement();
- if (RetReq.isTypeConstraint()) {
- if (getDerived().shouldVisitImplicitCode()) {
- TRY_TO(TraverseTemplateParameterListHelper(
- RetReq.getTypeConstraintTemplateParameterList()));
- } else {
- // Template parameter list is implicit, visit constraint directly.
- TRY_TO(TraverseTypeConstraint(RetReq.getTypeConstraint()));
- }
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseConceptNestedRequirement(
- concepts::NestedRequirement *R) {
- if (!R->hasInvalidConstraint())
- return getDerived().TraverseStmt(R->getConstraintExpr());
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
- // In pre-order traversal mode, each Traverse##STMT method is responsible for
- // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
- // does not call the default implementation, the WalkUpFrom callback is not
- // called. Post-order traversal mode should provide the same behavior
- // regarding method overrides.
- //
- // In post-order traversal mode the Traverse##STMT method, when it receives a
- // DataRecursionQueue, can't call WalkUpFrom after traversing children because
- // it only enqueues the children and does not traverse them. TraverseStmt
- // traverses the enqueued children, and we call WalkUpFrom here.
- //
- // However, to make pre-order and post-order modes identical with regards to
- // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the
- // user did not override the Traverse##STMT method. We implement the override
- // check with isSameMethod calls below.
- switch (S->getStmtClass()) {
- case Stmt::NoStmtClass:
- break;
- #define ABSTRACT_STMT(STMT)
- #define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: \
- if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
- &Derived::Traverse##CLASS)) { \
- TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \
- } \
- break;
- #define INITLISTEXPR(CLASS, PARENT) \
- case Stmt::CLASS##Class: \
- if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
- &Derived::Traverse##CLASS)) { \
- auto ILE = static_cast<CLASS *>(S); \
- if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \
- TRY_TO(WalkUpFrom##CLASS(Syn)); \
- if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
- TRY_TO(WalkUpFrom##CLASS(Sem)); \
- } \
- break;
- #include "clang/AST/StmtNodes.inc"
- }
- return true;
- }
- #undef DISPATCH_STMT
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S,
- DataRecursionQueue *Queue) {
- if (!S)
- return true;
- if (Queue) {
- Queue->push_back({S, false});
- return true;
- }
- SmallVector<llvm::PointerIntPair<Stmt *, 1, bool>, 8> LocalQueue;
- LocalQueue.push_back({S, false});
- while (!LocalQueue.empty()) {
- auto &CurrSAndVisited = LocalQueue.back();
- Stmt *CurrS = CurrSAndVisited.getPointer();
- bool Visited = CurrSAndVisited.getInt();
- if (Visited) {
- LocalQueue.pop_back();
- TRY_TO(dataTraverseStmtPost(CurrS));
- if (getDerived().shouldTraversePostOrder()) {
- TRY_TO(PostVisitStmt(CurrS));
- }
- continue;
- }
- if (getDerived().dataTraverseStmtPre(CurrS)) {
- CurrSAndVisited.setInt(true);
- size_t N = LocalQueue.size();
- TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
- // Process new children in the order they were added.
- std::reverse(LocalQueue.begin() + N, LocalQueue.end());
- } else {
- LocalQueue.pop_back();
- }
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
- if (T.isNull())
- return true;
- switch (T->getTypeClass()) {
- #define ABSTRACT_TYPE(CLASS, BASE)
- #define TYPE(CLASS, BASE) \
- case Type::CLASS: \
- return getDerived().Traverse##CLASS##Type( \
- static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())));
- #include "clang/AST/TypeNodes.inc"
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
- if (TL.isNull())
- return true;
- switch (TL.getTypeLocClass()) {
- #define ABSTRACT_TYPELOC(CLASS, BASE)
- #define TYPELOC(CLASS, BASE) \
- case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
- #include "clang/AST/TypeLocNodes.def"
- }
- return true;
- }
- // Define the Traverse*Attr(Attr* A) methods
- #define VISITORCLASS RecursiveASTVisitor
- #include "clang/AST/AttrVisitor.inc"
- #undef VISITORCLASS
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
- if (!D)
- return true;
- // As a syntax visitor, by default we want to ignore declarations for
- // implicit declarations (ones not typed explicitly by the user).
- if (!getDerived().shouldVisitImplicitCode() && D->isImplicit()) {
- // For an implicit template type parameter, its type constraints are not
- // implicit and are not represented anywhere else. We still need to visit
- // them.
- if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D))
- return TraverseTemplateTypeParamDeclConstraints(TTPD);
- return true;
- }
- switch (D->getKind()) {
- #define ABSTRACT_DECL(DECL)
- #define DECL(CLASS, BASE) \
- case Decl::CLASS: \
- if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
- return false; \
- break;
- #include "clang/AST/DeclNodes.inc"
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
- if (!NNS)
- return true;
- if (NNS->getPrefix())
- TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- return true;
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
- NestedNameSpecifierLoc NNS) {
- if (!NNS)
- return true;
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
- switch (NNS.getNestedNameSpecifier()->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- return true;
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate:
- TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
- break;
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
- DeclarationNameInfo NameInfo) {
- switch (NameInfo.getName().getNameKind()) {
- case DeclarationName::CXXConstructorName:
- case DeclarationName::CXXDestructorName:
- case DeclarationName::CXXConversionFunctionName:
- if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
- TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
- break;
- case DeclarationName::CXXDeductionGuideName:
- TRY_TO(TraverseTemplateName(
- TemplateName(NameInfo.getName().getCXXDeductionGuideTemplate())));
- break;
- case DeclarationName::Identifier:
- case DeclarationName::ObjCZeroArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::CXXOperatorName:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXUsingDirective:
- break;
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
- if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
- else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
- const TemplateArgument &Arg) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
- case TemplateArgument::Type:
- return getDerived().TraverseType(Arg.getAsType());
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(Arg.getAsExpr());
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_elements());
- }
- return true;
- }
- // FIXME: no template name location?
- // FIXME: no source locations for a template argument pack?
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
- const TemplateArgumentLoc &ArgLoc) {
- const TemplateArgument &Arg = ArgLoc.getArgument();
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- return true;
- case TemplateArgument::Type: {
- // FIXME: how can TSI ever be NULL?
- if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
- return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
- else
- return getDerived().TraverseType(Arg.getAsType());
- }
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion:
- if (ArgLoc.getTemplateQualifierLoc())
- TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
- ArgLoc.getTemplateQualifierLoc()));
- return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
- case TemplateArgument::Expression:
- return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
- case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_elements());
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- ArrayRef<TemplateArgument> Args) {
- for (const TemplateArgument &Arg : Args)
- TRY_TO(TraverseTemplateArgument(Arg));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
- CXXCtorInitializer *Init) {
- if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
- TRY_TO(TraverseStmt(Init->getInit()));
- return true;
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
- const LambdaCapture *C,
- Expr *Init) {
- if (LE->isInitCapture(C))
- TRY_TO(TraverseDecl(C->getCapturedVar()));
- else
- TRY_TO(TraverseStmt(Init));
- return true;
- }
- // ----------------- Type traversal -----------------
- // This macro makes available a variable T, the passed-in type.
- #define DEF_TRAVERSE_TYPE(TYPE, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
- if (!getDerived().shouldTraversePostOrder()) \
- TRY_TO(WalkUpFrom##TYPE(T)); \
- { CODE; } \
- if (getDerived().shouldTraversePostOrder()) \
- TRY_TO(WalkUpFrom##TYPE(T)); \
- return true; \
- }
- DEF_TRAVERSE_TYPE(BuiltinType, {})
- DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
- DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
- DEF_TRAVERSE_TYPE(BlockPointerType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
- DEF_TRAVERSE_TYPE(LValueReferenceType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
- DEF_TRAVERSE_TYPE(RValueReferenceType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
- DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
- TRY_TO(TraverseType(T->getPointeeType()));
- })
- DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
- DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
- DEF_TRAVERSE_TYPE(ConstantArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr())));
- })
- DEF_TRAVERSE_TYPE(IncompleteArrayType,
- { TRY_TO(TraverseType(T->getElementType())); })
- DEF_TRAVERSE_TYPE(VariableArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
- DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
- DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
- TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
- TRY_TO(TraverseType(T->getPointeeType()));
- })
- DEF_TRAVERSE_TYPE(DependentVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
- })
- DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
- })
- DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
- DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
- DEF_TRAVERSE_TYPE(ConstantMatrixType,
- { TRY_TO(TraverseType(T->getElementType())); })
- DEF_TRAVERSE_TYPE(DependentSizedMatrixType, {
- if (T->getRowExpr())
- TRY_TO(TraverseStmt(T->getRowExpr()));
- if (T->getColumnExpr())
- TRY_TO(TraverseStmt(T->getColumnExpr()));
- TRY_TO(TraverseType(T->getElementType()));
- })
- DEF_TRAVERSE_TYPE(FunctionNoProtoType,
- { TRY_TO(TraverseType(T->getReturnType())); })
- DEF_TRAVERSE_TYPE(FunctionProtoType, {
- TRY_TO(TraverseType(T->getReturnType()));
- for (const auto &A : T->param_types()) {
- TRY_TO(TraverseType(A));
- }
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO(TraverseStmt(NE));
- })
- DEF_TRAVERSE_TYPE(UsingType, {})
- DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
- DEF_TRAVERSE_TYPE(TypedefType, {})
- DEF_TRAVERSE_TYPE(TypeOfExprType,
- { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
- DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); })
- DEF_TRAVERSE_TYPE(DecltypeType,
- { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
- DEF_TRAVERSE_TYPE(UnaryTransformType, {
- TRY_TO(TraverseType(T->getBaseType()));
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
- DEF_TRAVERSE_TYPE(AutoType, {
- TRY_TO(TraverseType(T->getDeducedType()));
- if (T->isConstrained()) {
- TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
- }
- })
- DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseType(T->getDeducedType()));
- })
- DEF_TRAVERSE_TYPE(RecordType, {})
- DEF_TRAVERSE_TYPE(EnumType, {})
- DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
- DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {
- TRY_TO(TraverseType(T->getReplacementType()));
- })
- DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {
- TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
- })
- DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->template_arguments()));
- })
- DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
- DEF_TRAVERSE_TYPE(AttributedType,
- { TRY_TO(TraverseType(T->getModifiedType())); })
- DEF_TRAVERSE_TYPE(BTFTagAttributedType,
- { TRY_TO(TraverseType(T->getWrappedType())); })
- DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
- DEF_TRAVERSE_TYPE(MacroQualifiedType,
- { TRY_TO(TraverseType(T->getUnderlyingType())); })
- DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
- })
- DEF_TRAVERSE_TYPE(DependentNameType,
- { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
- DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->template_arguments()));
- })
- DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
- DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
- DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
- DEF_TRAVERSE_TYPE(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- TRY_TO(TraverseType(T->getBaseType()));
- for (auto typeArg : T->getTypeArgsAsWritten()) {
- TRY_TO(TraverseType(typeArg));
- }
- })
- DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
- { TRY_TO(TraverseType(T->getPointeeType())); })
- DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
- DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
- DEF_TRAVERSE_TYPE(BitIntType, {})
- DEF_TRAVERSE_TYPE(DependentBitIntType,
- { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
- #undef DEF_TRAVERSE_TYPE
- // ----------------- TypeLoc traversal -----------------
- // This macro makes available a variable TL, the passed-in TypeLoc.
- // If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
- // in addition to WalkUpFrom* for the TypeLoc itself, such that existing
- // clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
- // continue to work.
- #define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (!getDerived().shouldTraversePostOrder()) { \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
- } \
- { CODE; } \
- if (getDerived().shouldTraversePostOrder()) { \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
- } \
- return true; \
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
- // Move this over to the 'main' typeloc tree. Note that this is a
- // move -- we pretend that we were really looking at the unqualified
- // typeloc all along -- rather than a recursion, so we don't follow
- // the normal CRTP plan of going through
- // getDerived().TraverseTypeLoc. If we did, we'd be traversing
- // twice for the same type (once as a QualifiedTypeLoc version of
- // the type, once as an UnqualifiedTypeLoc version of the type),
- // which in effect means we'd call VisitTypeLoc twice with the
- // 'same' type. This solves that problem, at the cost of never
- // seeing the qualified version of the type (unless the client
- // subclasses TraverseQualifiedTypeLoc themselves). It's not a
- // perfect solution. A perfect solution probably requires making
- // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
- // wrapper around Type* -- rather than being its own class in the
- // type hierarchy.
- return TraverseTypeLoc(TL.getUnqualifiedLoc());
- }
- DEF_TRAVERSE_TYPELOC(BuiltinType, {})
- // FIXME: ComplexTypeLoc is unfinished
- DEF_TRAVERSE_TYPELOC(ComplexType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
- DEF_TRAVERSE_TYPELOC(PointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
- DEF_TRAVERSE_TYPELOC(BlockPointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
- DEF_TRAVERSE_TYPELOC(LValueReferenceType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
- DEF_TRAVERSE_TYPELOC(RValueReferenceType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
- // We traverse this in the type case as well, but how is it not reached through
- // the pointee type?
- DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- if (auto *TSI = TL.getClassTInfo())
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- else
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
- DEF_TRAVERSE_TYPELOC(AdjustedType,
- { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
- DEF_TRAVERSE_TYPELOC(DecayedType,
- { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
- // This isn't available for ArrayType, but is for the ArrayTypeLoc.
- TRY_TO(TraverseStmt(TL.getSizeExpr()));
- return true;
- }
- DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- TRY_TO(TraverseArrayTypeLocHelper(TL));
- })
- DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- TRY_TO(TraverseArrayTypeLocHelper(TL));
- })
- DEF_TRAVERSE_TYPELOC(VariableArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- TRY_TO(TraverseArrayTypeLocHelper(TL));
- })
- DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- TRY_TO(TraverseArrayTypeLocHelper(TL));
- })
- DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
- })
- // FIXME: order? why not size expr first?
- // FIXME: base VectorTypeLoc is unfinished
- DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
- // FIXME: VectorTypeLoc is unfinished
- DEF_TRAVERSE_TYPELOC(VectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
- DEF_TRAVERSE_TYPELOC(DependentVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
- // FIXME: size and attributes
- // FIXME: base VectorTypeLoc is unfinished
- DEF_TRAVERSE_TYPELOC(ExtVectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
- DEF_TRAVERSE_TYPELOC(ConstantMatrixType, {
- TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
- TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
- DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, {
- TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
- TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
- DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
- { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
- // FIXME: location of exception specifications (attributes?)
- DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
- const FunctionProtoType *T = TL.getTypePtr();
- for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
- if (TL.getParam(I)) {
- TRY_TO(TraverseDecl(TL.getParam(I)));
- } else if (I < T->getNumParams()) {
- TRY_TO(TraverseType(T->getParamType(I)));
- }
- }
- for (const auto &E : T->exceptions()) {
- TRY_TO(TraverseType(E));
- }
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO(TraverseStmt(NE));
- })
- DEF_TRAVERSE_TYPELOC(UsingType, {})
- DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
- DEF_TRAVERSE_TYPELOC(TypedefType, {})
- DEF_TRAVERSE_TYPELOC(TypeOfExprType,
- { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
- DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
- })
- // FIXME: location of underlying expr
- DEF_TRAVERSE_TYPELOC(DecltypeType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
- })
- DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_TYPELOC(AutoType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
- if (TL.isConstrained()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
- DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
- })
- DEF_TRAVERSE_TYPELOC(RecordType, {})
- DEF_TRAVERSE_TYPELOC(EnumType, {})
- DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
- DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
- })
- DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {
- TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
- })
- // FIXME: use the loc for the template name?
- DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
- DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
- DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
- DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
- { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
- DEF_TRAVERSE_TYPELOC(AttributedType,
- { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
- DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
- { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
- DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
- })
- DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- })
- DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
- DEF_TRAVERSE_TYPELOC(PackExpansionType,
- { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
- DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
- for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
- ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
- TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
- }
- })
- DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
- DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
- TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
- for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
- TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
- for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
- ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
- TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
- }
- })
- DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
- { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
- DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
- DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
- DEF_TRAVERSE_TYPELOC(BitIntType, {})
- DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
- })
- #undef DEF_TRAVERSE_TYPELOC
- // ----------------- Decl traversal -----------------
- //
- // For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
- // the children that come from the DeclContext associated with it.
- // Therefore each Traverse* only needs to worry about children other
- // than those.
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::canIgnoreChildDeclWhileTraversingDeclContext(
- const Decl *Child) {
- // BlockDecls are traversed through BlockExprs,
- // CapturedDecls are traversed through CapturedStmts.
- if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
- return true;
- // Lambda classes are traversed through LambdaExprs.
- if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
- return Cls->isLambda();
- return false;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
- if (!DC)
- return true;
- for (auto *Child : DC->decls()) {
- if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
- TRY_TO(TraverseDecl(Child));
- }
- return true;
- }
- // This macro makes available a variable D, the passed-in decl.
- #define DEF_TRAVERSE_DECL(DECL, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
- bool ShouldVisitChildren = true; \
- bool ReturnValue = true; \
- if (!getDerived().shouldTraversePostOrder()) \
- TRY_TO(WalkUpFrom##DECL(D)); \
- { CODE; } \
- if (ReturnValue && ShouldVisitChildren) \
- TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
- if (ReturnValue) { \
- /* Visit any attributes attached to this declaration. */ \
- for (auto *I : D->attrs()) \
- TRY_TO(getDerived().TraverseAttr(I)); \
- } \
- if (ReturnValue && getDerived().shouldTraversePostOrder()) \
- TRY_TO(WalkUpFrom##DECL(D)); \
- return ReturnValue; \
- }
- DEF_TRAVERSE_DECL(AccessSpecDecl, {})
- DEF_TRAVERSE_DECL(BlockDecl, {
- if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- TRY_TO(TraverseStmt(D->getBody()));
- for (const auto &I : D->captures()) {
- if (I.hasCopyExpr()) {
- TRY_TO(TraverseStmt(I.getCopyExpr()));
- }
- }
- ShouldVisitChildren = false;
- })
- DEF_TRAVERSE_DECL(CapturedDecl, {
- TRY_TO(TraverseStmt(D->getBody()));
- ShouldVisitChildren = false;
- })
- DEF_TRAVERSE_DECL(EmptyDecl, {})
- DEF_TRAVERSE_DECL(HLSLBufferDecl, {})
- DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, {
- TRY_TO(TraverseStmt(D->getTemporaryExpr()));
- })
- DEF_TRAVERSE_DECL(FileScopeAsmDecl,
- { TRY_TO(TraverseStmt(D->getAsmString())); })
- DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
- DEF_TRAVERSE_DECL(ImportDecl, {})
- DEF_TRAVERSE_DECL(FriendDecl, {
- // Friend is either decl or a type.
- if (D->getFriendType()) {
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- // Traverse any CXXRecordDecl owned by this type, since
- // it will not be in the parent context:
- if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
- TRY_TO(TraverseDecl(ET->getOwnedTagDecl()));
- } else {
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- }
- })
- DEF_TRAVERSE_DECL(FriendTemplateDecl, {
- if (D->getFriendType())
- TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
- TRY_TO(TraverseDecl(D->getFriendDecl()));
- for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
- TemplateParameterList *TPL = D->getTemplateParameterList(I);
- for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
- ITPL != ETPL; ++ITPL) {
- TRY_TO(TraverseDecl(*ITPL));
- }
- }
- })
- DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
- if (D->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten()->getTemplateArgs(),
- D->getTemplateArgsAsWritten()->NumTemplateArgs));
- }
- })
- DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
- DEF_TRAVERSE_DECL(ExportDecl, {})
- DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
- })
- DEF_TRAVERSE_DECL(StaticAssertDecl, {
- TRY_TO(TraverseStmt(D->getAssertExpr()));
- TRY_TO(TraverseStmt(D->getMessage()));
- })
- DEF_TRAVERSE_DECL(TranslationUnitDecl, {
- // Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- // If the traversal scope is set, then consider them to be the children of
- // the TUDecl, rather than traversing (and loading?) all top-level decls.
- auto Scope = D->getASTContext().getTraversalScope();
- bool HasLimitedScope =
- Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
- if (HasLimitedScope) {
- ShouldVisitChildren = false; // we'll do that here instead
- for (auto *Child : Scope) {
- if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
- TRY_TO(TraverseDecl(Child));
- }
- }
- })
- DEF_TRAVERSE_DECL(PragmaCommentDecl, {})
- DEF_TRAVERSE_DECL(PragmaDetectMismatchDecl, {})
- DEF_TRAVERSE_DECL(ExternCContextDecl, {})
- DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // We shouldn't traverse an aliased namespace, since it will be
- // defined (and, therefore, traversed) somewhere else.
- ShouldVisitChildren = false;
- })
- DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
- })
- DEF_TRAVERSE_DECL(
- NamespaceDecl,
- {// Code in an unnamed namespace shows up automatically in
- // decls_begin()/decls_end(). Thus we don't need to recurse on
- // D->getAnonymousNamespace().
- })
- DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
- })
- DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
- if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
- for (auto typeParam : *typeParamList) {
- TRY_TO(TraverseObjCTypeParamDecl(typeParam));
- }
- }
- for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
- ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
- TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
- }
- })
- DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
- })
- DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
- })
- DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
- if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
- for (auto typeParam : *typeParamList) {
- TRY_TO(TraverseObjCTypeParamDecl(typeParam));
- }
- }
- if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
- TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
- }
- if (D->isThisDeclarationADefinition()) {
- for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
- ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
- TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
- }
- }
- })
- DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
- if (D->isThisDeclarationADefinition()) {
- for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
- ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
- TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
- }
- }
- })
- DEF_TRAVERSE_DECL(ObjCMethodDecl, {
- if (D->getReturnTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
- }
- for (ParmVarDecl *Parameter : D->parameters()) {
- TRY_TO(TraverseDecl(Parameter));
- }
- if (D->isThisDeclarationADefinition()) {
- TRY_TO(TraverseStmt(D->getBody()));
- }
- ShouldVisitChildren = false;
- })
- DEF_TRAVERSE_DECL(ObjCTypeParamDecl, {
- if (D->hasExplicitBound()) {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
- }
- })
- DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
- if (D->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- else
- TRY_TO(TraverseType(D->getType()));
- ShouldVisitChildren = false;
- })
- DEF_TRAVERSE_DECL(UsingDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
- DEF_TRAVERSE_DECL(UsingEnumDecl,
- { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
- DEF_TRAVERSE_DECL(UsingPackDecl, {})
- DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- })
- DEF_TRAVERSE_DECL(UsingShadowDecl, {})
- DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {})
- DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
- for (auto *I : D->varlists()) {
- TRY_TO(TraverseStmt(I));
- }
- })
- DEF_TRAVERSE_DECL(OMPRequiresDecl, {
- for (auto *C : D->clauselists()) {
- TRY_TO(TraverseOMPClause(C));
- }
- })
- DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
- TRY_TO(TraverseStmt(D->getCombiner()));
- if (auto *Initializer = D->getInitializer())
- TRY_TO(TraverseStmt(Initializer));
- TRY_TO(TraverseType(D->getType()));
- return true;
- })
- DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, {
- for (auto *C : D->clauselists())
- TRY_TO(TraverseOMPClause(C));
- TRY_TO(TraverseType(D->getType()));
- return true;
- })
- DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
- DEF_TRAVERSE_DECL(OMPAllocateDecl, {
- for (auto *I : D->varlists())
- TRY_TO(TraverseStmt(I));
- for (auto *C : D->clauselists())
- TRY_TO(TraverseOMPClause(C));
- })
- // A helper method for TemplateDecl's children.
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
- TemplateParameterList *TPL) {
- if (TPL) {
- for (NamedDecl *D : *TPL) {
- TRY_TO(TraverseDecl(D));
- }
- if (Expr *RequiresClause = TPL->getRequiresClause()) {
- TRY_TO(TraverseStmt(RequiresClause));
- }
- }
- return true;
- }
- template <typename Derived>
- template <typename T>
- bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
- for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
- TemplateParameterList *TPL = D->getTemplateParameterList(i);
- TraverseTemplateParameterListHelper(TPL);
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- ClassTemplateDecl *D) {
- for (auto *SD : D->specializations()) {
- for (auto *RD : SD->redecls()) {
- assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
- switch (
- cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
- // Visit the implicit instantiations with the requested pattern.
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(RD));
- break;
- // We don't need to do anything on an explicit instantiation
- // or explicit specialization because there will be an explicit
- // node for it elsewhere.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- VarTemplateDecl *D) {
- for (auto *SD : D->specializations()) {
- for (auto *RD : SD->redecls()) {
- switch (
- cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- TRY_TO(TraverseDecl(RD));
- break;
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
- return true;
- }
- // A helper method for traversing the instantiations of a
- // function while skipping its specializations.
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
- FunctionTemplateDecl *D) {
- for (auto *FD : D->specializations()) {
- for (auto *RD : FD->redecls()) {
- switch (RD->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- // We don't know what kind of FunctionDecl this is.
- TRY_TO(TraverseDecl(RD));
- break;
- // FIXME: For now traverse explicit instantiations here. Change that
- // once they are represented as dedicated nodes in the AST.
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- TRY_TO(TraverseDecl(RD));
- break;
- case TSK_ExplicitSpecialization:
- break;
- }
- }
- }
- return true;
- }
- // This macro unifies the traversal of class, variable and function
- // template declarations.
- #define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
- TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
- \
- /* By default, we do not traverse the instantiations of \
- class templates since they do not appear in the user code. The \
- following code optionally traverses them. \
- \
- We only traverse the class instantiations when we see the canonical \
- declaration of the template, to ensure we only visit them once. */ \
- if (getDerived().shouldVisitTemplateInstantiations() && \
- D == D->getCanonicalDecl()) \
- TRY_TO(TraverseTemplateInstantiations(D)); \
- \
- /* Note that getInstantiatedFromMemberTemplate() is just a link \
- from a template instantiation back to the template from which \
- it was instantiated, and thus should not be traversed. */ \
- })
- DEF_TRAVERSE_TMPL_DECL(Class)
- DEF_TRAVERSE_TMPL_DECL(Var)
- DEF_TRAVERSE_TMPL_DECL(Function)
- DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
- // D is the "T" in something like
- // template <template <typename> class T> class container { };
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
- DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
- const TemplateTypeParmDecl *D) {
- if (const auto *TC = D->getTypeConstraint())
- TRY_TO(TraverseTypeConstraint(TC));
- return true;
- }
- DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
- // D is the "T" in something like "template<typename T> class vector;"
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
- TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_DECL(TypedefDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the typedef, not something that was written in the
- // source.
- })
- DEF_TRAVERSE_DECL(TypeAliasDecl, {
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type alias, not something that was written in the
- // source.
- })
- DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
- TRY_TO(TraverseDecl(D->getTemplatedDecl()));
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- })
- DEF_TRAVERSE_DECL(ConceptDecl, {
- TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
- TRY_TO(TraverseStmt(D->getConstraintExpr()));
- })
- DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
- // A dependent using declaration which was marked with 'typename'.
- // template<class T> class A : public B<T> { using typename B<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the
- // source.
- })
- DEF_TRAVERSE_DECL(UnresolvedUsingIfExistsDecl, {})
- DEF_TRAVERSE_DECL(EnumDecl, {
- TRY_TO(TraverseDeclTemplateParameterLists(D));
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- if (auto *TSI = D->getIntegerTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- // The enumerators are already traversed by
- // decls_begin()/decls_end().
- })
- // Helper methods for RecordDecl and its children.
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
- // We shouldn't traverse D->getTypeForDecl(); it's a result of
- // declaring the type, not something that was written in the source.
- TRY_TO(TraverseDeclTemplateParameterLists(D));
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseCXXBaseSpecifier(
- const CXXBaseSpecifier &Base) {
- TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
- if (!TraverseRecordHelper(D))
- return false;
- if (D->isCompleteDefinition()) {
- for (const auto &I : D->bases()) {
- TRY_TO(TraverseCXXBaseSpecifier(I));
- }
- // We don't traverse the friends or the conversions, as they are
- // already in decls_begin()/decls_end().
- }
- return true;
- }
- DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
- DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
- #define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
- /* For implicit instantiations ("set<int> x;"), we don't want to \
- recurse at all, since the instatiated template isn't written in \
- the source code anywhere. (Note the instatiated *type* -- \
- set<int> -- is written, and will still get a callback of \
- TemplateSpecializationType). For explicit instantiations \
- ("template set<int>;"), we do need a callback, since this \
- is the only callback that's made for this instantiation. \
- We use getTypeAsWritten() to distinguish. */ \
- if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
- \
- if (getDerived().shouldVisitTemplateInstantiations() || \
- D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
- /* Traverse base definition for explicit specializations */ \
- TRY_TO(Traverse##DECLKIND##Helper(D)); \
- } else { \
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
- \
- /* Returning from here skips traversing the \
- declaration context of the *TemplateSpecializationDecl \
- (embedded in the DEF_TRAVERSE_DECL() macro) \
- which contains the instantiated members of the template. */ \
- return true; \
- } \
- })
- DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord)
- DEF_TRAVERSE_TMPL_SPEC_DECL(Var, Var)
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
- const TemplateArgumentLoc *TAL, unsigned Count) {
- for (unsigned I = 0; I < Count; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
- }
- return true;
- }
- #define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
- DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
- /* The partial specialization. */ \
- if (TemplateParameterList *TPL = D->getTemplateParameters()) { \
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
- I != E; ++I) { \
- TRY_TO(TraverseDecl(*I)); \
- } \
- } \
- /* The args that remains unspecialized. */ \
- TRY_TO(TraverseTemplateArgumentLocsHelper( \
- D->getTemplateArgsAsWritten()->getTemplateArgs(), \
- D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
- \
- /* Don't need the *TemplatePartialSpecializationHelper, even \
- though that's our parent class -- we already visit all the \
- template args here. */ \
- TRY_TO(Traverse##DECLKIND##Helper(D)); \
- \
- /* Instantiations will have been visited with the primary template. */ \
- })
- DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
- DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
- DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
- DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
- // Like UnresolvedUsingTypenameDecl, but without the 'typename':
- // template <class T> Class A : public Base<T> { using Base<T>::foo; };
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- })
- DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
- TRY_TO(TraverseDeclTemplateParameterLists(D));
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- if (D->getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
- else
- TRY_TO(TraverseType(D->getType()));
- return true;
- }
- DEF_TRAVERSE_DECL(DecompositionDecl, {
- TRY_TO(TraverseVarHelper(D));
- for (auto *Binding : D->bindings()) {
- TRY_TO(TraverseDecl(Binding));
- }
- })
- DEF_TRAVERSE_DECL(BindingDecl, {
- if (getDerived().shouldVisitImplicitCode())
- TRY_TO(TraverseStmt(D->getBinding()));
- })
- DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
- DEF_TRAVERSE_DECL(MSGuidDecl, {})
- DEF_TRAVERSE_DECL(UnnamedGlobalConstantDecl, {})
- DEF_TRAVERSE_DECL(TemplateParamObjectDecl, {})
- DEF_TRAVERSE_DECL(FieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
- TRY_TO(TraverseStmt(D->getInClassInitializer()));
- })
- DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
- DEF_TRAVERSE_DECL(ObjCIvarDecl, {
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->isBitField())
- TRY_TO(TraverseStmt(D->getBitWidth()));
- // FIXME: implement the rest.
- })
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
- TRY_TO(TraverseDeclTemplateParameterLists(D));
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
- // If we're an explicit template specialization, iterate over the
- // template args that were explicitly specified. If we were doing
- // this in typing order, we'd do it between the return type and
- // the function args, but both are handled by the FunctionTypeLoc
- // above, so we have to choose one side. I've decided to do before.
- if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo()) {
- if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
- FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
- // A specialization might not have explicit template arguments if it has
- // a templated return type and concrete arguments.
- if (const ASTTemplateArgumentListInfo *TALI =
- FTSI->TemplateArgumentsAsWritten) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
- TALI->NumTemplateArgs));
- }
- }
- }
- // Visit the function type itself, which can be either
- // FunctionNoProtoType or FunctionProtoType, or a typedef. This
- // also covers the return type and the function parameters,
- // including exception specifications.
- if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- } else if (getDerived().shouldVisitImplicitCode()) {
- // Visit parameter variable declarations of the implicit function
- // if the traverser is visiting implicit code. Parameter variable
- // declarations do not have valid TypeSourceInfo, so to visit them
- // we need to traverse the declarations explicitly.
- for (ParmVarDecl *Parameter : D->parameters()) {
- TRY_TO(TraverseDecl(Parameter));
- }
- }
- // Visit the trailing requires clause, if any.
- if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
- TRY_TO(TraverseStmt(TrailingRequiresClause));
- }
- if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
- // Constructor initializers.
- for (auto *I : Ctor->inits()) {
- if (I->isWritten() || getDerived().shouldVisitImplicitCode())
- TRY_TO(TraverseConstructorInitializer(I));
- }
- }
- bool VisitBody =
- D->isThisDeclarationADefinition() &&
- // Don't visit the function body if the function definition is generated
- // by clang.
- (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
- if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
- if (const CXXRecordDecl *RD = MD->getParent()) {
- if (RD->isLambda() &&
- declaresSameEntity(RD->getLambdaCallOperator(), MD)) {
- VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
- }
- }
- }
- if (VisitBody) {
- TRY_TO(TraverseStmt(D->getBody()));
- // Body may contain using declarations whose shadows are parented to the
- // FunctionDecl itself.
- for (auto *Child : D->decls()) {
- if (isa<UsingShadowDecl>(Child))
- TRY_TO(TraverseDecl(Child));
- }
- }
- return true;
- }
- DEF_TRAVERSE_DECL(FunctionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- ShouldVisitChildren = false;
- ReturnValue = TraverseFunctionHelper(D);
- })
- DEF_TRAVERSE_DECL(CXXDeductionGuideDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- ShouldVisitChildren = false;
- ReturnValue = TraverseFunctionHelper(D);
- })
- DEF_TRAVERSE_DECL(CXXMethodDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- ShouldVisitChildren = false;
- ReturnValue = TraverseFunctionHelper(D);
- })
- DEF_TRAVERSE_DECL(CXXConstructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- ShouldVisitChildren = false;
- ReturnValue = TraverseFunctionHelper(D);
- })
- // CXXConversionDecl is the declaration of a type conversion operator.
- // It's not a cast expression.
- DEF_TRAVERSE_DECL(CXXConversionDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- ShouldVisitChildren = false;
- ReturnValue = TraverseFunctionHelper(D);
- })
- DEF_TRAVERSE_DECL(CXXDestructorDecl, {
- // We skip decls_begin/decls_end, which are already covered by
- // TraverseFunctionHelper().
- ShouldVisitChildren = false;
- ReturnValue = TraverseFunctionHelper(D);
- })
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
- TRY_TO(TraverseDeclaratorHelper(D));
- // Default params are taken care of when we traverse the ParmVarDecl.
- if (!isa<ParmVarDecl>(D) &&
- (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
- TRY_TO(TraverseStmt(D->getInit()));
- return true;
- }
- DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
- DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
- DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
- // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
- TRY_TO(TraverseDeclaratorHelper(D));
- if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
- TRY_TO(TraverseStmt(D->getDefaultArgument()));
- })
- DEF_TRAVERSE_DECL(ParmVarDecl, {
- TRY_TO(TraverseVarHelper(D));
- if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
- if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
- !D->hasUnparsedDefaultArg())
- TRY_TO(TraverseStmt(D->getDefaultArg()));
- })
- DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
- DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
- TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
- })
- #undef DEF_TRAVERSE_DECL
- // ----------------- Stmt traversal -----------------
- //
- // For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
- // over the children defined in children() (every stmt defines these,
- // though sometimes the range is empty). Each individual Traverse*
- // method only needs to worry about children other than those. To see
- // what children() does for a given class, see, e.g.,
- // http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
- // This macro makes available a variable S, the passed-in stmt.
- #define DEF_TRAVERSE_STMT(STMT, CODE) \
- template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##STMT( \
- STMT *S, DataRecursionQueue *Queue) { \
- bool ShouldVisitChildren = true; \
- bool ReturnValue = true; \
- if (!getDerived().shouldTraversePostOrder()) \
- TRY_TO(WalkUpFrom##STMT(S)); \
- { CODE; } \
- if (ShouldVisitChildren) { \
- for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
- } \
- } \
- /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
- * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
- * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
- * children. */ \
- if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
- TRY_TO(WalkUpFrom##STMT(S)); \
- } \
- return ReturnValue; \
- }
- DEF_TRAVERSE_STMT(GCCAsmStmt, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
- for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
- }
- for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
- }
- // children() iterates over inputExpr and outputExpr.
- })
- DEF_TRAVERSE_STMT(
- MSAsmStmt,
- {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
- // added this needs to be implemented.
- })
- DEF_TRAVERSE_STMT(CXXCatchStmt, {
- TRY_TO(TraverseDecl(S->getExceptionDecl()));
- // children() iterates over the handler block.
- })
- DEF_TRAVERSE_STMT(DeclStmt, {
- for (auto *I : S->decls()) {
- TRY_TO(TraverseDecl(I));
- }
- // Suppress the default iteration over children() by
- // returning. Here's why: A DeclStmt looks like 'type var [=
- // initializer]'. The decls above already traverse over the
- // initializers, so we don't have to do it again (which
- // children() would do).
- ShouldVisitChildren = false;
- })
- // These non-expr stmts (most of them), do not need any action except
- // iterating over the children.
- DEF_TRAVERSE_STMT(BreakStmt, {})
- DEF_TRAVERSE_STMT(CXXTryStmt, {})
- DEF_TRAVERSE_STMT(CaseStmt, {})
- DEF_TRAVERSE_STMT(CompoundStmt, {})
- DEF_TRAVERSE_STMT(ContinueStmt, {})
- DEF_TRAVERSE_STMT(DefaultStmt, {})
- DEF_TRAVERSE_STMT(DoStmt, {})
- DEF_TRAVERSE_STMT(ForStmt, {})
- DEF_TRAVERSE_STMT(GotoStmt, {})
- DEF_TRAVERSE_STMT(IfStmt, {})
- DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
- DEF_TRAVERSE_STMT(LabelStmt, {})
- DEF_TRAVERSE_STMT(AttributedStmt, {})
- DEF_TRAVERSE_STMT(NullStmt, {})
- DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
- DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
- DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
- DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
- DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
- DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
- DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
- DEF_TRAVERSE_STMT(CXXForRangeStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- if (S->getInit())
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
- // Visit everything else only if shouldVisitImplicitCode().
- ShouldVisitChildren = false;
- }
- })
- DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- })
- DEF_TRAVERSE_STMT(ReturnStmt, {})
- DEF_TRAVERSE_STMT(SwitchStmt, {})
- DEF_TRAVERSE_STMT(WhileStmt, {})
- DEF_TRAVERSE_STMT(ConstantExpr, {})
- DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
- })
- DEF_TRAVERSE_STMT(DeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- })
- DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
- })
- DEF_TRAVERSE_STMT(MemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- })
- DEF_TRAVERSE_STMT(
- ImplicitCastExpr,
- {// We don't traverse the cast type, as it's not written in the
- // source code.
- })
- DEF_TRAVERSE_STMT(CStyleCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXConstCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(BuiltinBitCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
- InitListExpr *S, DataRecursionQueue *Queue) {
- if (S) {
- // Skip this if we traverse postorder. We will visit it later
- // in PostVisitStmt.
- if (!getDerived().shouldTraversePostOrder())
- TRY_TO(WalkUpFromInitListExpr(S));
- // All we need are the default actions. FIXME: use a helper function.
- for (Stmt *SubStmt : S->children()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);
- }
- if (!Queue && getDerived().shouldTraversePostOrder())
- TRY_TO(WalkUpFromInitListExpr(S));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseObjCProtocolLoc(
- ObjCProtocolLoc ProtocolLoc) {
- return true;
- }
- // If shouldVisitImplicitCode() returns false, this method traverses only the
- // syntactic form of InitListExpr.
- // If shouldVisitImplicitCode() return true, this method is called once for
- // each pair of syntactic and semantic InitListExpr, and it traverses the
- // subtrees defined by the two forms. This may cause some of the children to be
- // visited twice, if they appear both in the syntactic and the semantic form.
- //
- // There is no guarantee about which form \p S takes when this method is called.
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
- InitListExpr *S, DataRecursionQueue *Queue) {
- if (S->isSemanticForm() && S->isSyntacticForm()) {
- // `S` does not have alternative forms, traverse only once.
- TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
- return true;
- }
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
- if (getDerived().shouldVisitImplicitCode()) {
- // Only visit the semantic form if the clients are interested in implicit
- // compiler-generated.
- TRY_TO(TraverseSynOrSemInitListExpr(
- S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
- }
- return true;
- }
- // GenericSelectionExpr is a special case because the types and expressions
- // are interleaved. We also need to watch out for null types (default
- // generic associations).
- DEF_TRAVERSE_STMT(GenericSelectionExpr, {
- TRY_TO(TraverseStmt(S->getControllingExpr()));
- for (const GenericSelectionExpr::Association Assoc : S->associations()) {
- if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
- }
- ShouldVisitChildren = false;
- })
- // PseudoObjectExpr is a special case because of the weirdness with
- // syntactic expressions and opaque values.
- DEF_TRAVERSE_STMT(PseudoObjectExpr, {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
- for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
- e = S->semantics_end();
- i != e; ++i) {
- Expr *sub = *i;
- if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
- sub = OVE->getSourceExpr();
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub);
- }
- ShouldVisitChildren = false;
- })
- DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
- // This is called for code like 'return T()' where T is a built-in
- // (i.e. non-class) type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXNewExpr, {
- // The child-iterator will pick up the other arguments.
- TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(OffsetOfExpr, {
- // The child-iterator will pick up the expression representing
- // the field.
- // FIMXE: for code like offsetof(Foo, a.b.c), should we get
- // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isArgumentType())
- TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXTypeidExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- })
- DEF_TRAVERSE_STMT(MSPropertySubscriptExpr, {})
- DEF_TRAVERSE_STMT(CXXUuidofExpr, {
- // The child-iterator will pick up the arg if it's an expression,
- // but not if it's a type.
- if (S->isTypeOperand())
- TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(TypeTraitExpr, {
- for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
- TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
- TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(ExpressionTraitExpr,
- { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
- DEF_TRAVERSE_STMT(VAArgExpr, {
- // The child-iterator will pick up the expression argument.
- TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
- // This is called for code like 'return T()' where T is a class type.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
- // Walk only the visible parts of lambda expressions.
- DEF_TRAVERSE_STMT(LambdaExpr, {
- // Visit the capture list.
- for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
- const LambdaCapture *C = S->capture_begin() + I;
- if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
- TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
- }
- }
- if (getDerived().shouldVisitImplicitCode()) {
- // The implicit model is simple: everything else is in the lambda class.
- TRY_TO(TraverseDecl(S->getLambdaClass()));
- } else {
- // We need to poke around to find the bits that might be explicitly written.
- TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
- TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
- if (S->hasExplicitParameters()) {
- // Visit parameters.
- for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
- TRY_TO(TraverseDecl(Proto.getParam(I)));
- }
- auto *T = Proto.getTypePtr();
- for (const auto &E : T->exceptions())
- TRY_TO(TraverseType(E));
- if (Expr *NE = T->getNoexceptExpr())
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
- if (S->hasExplicitResultType())
- TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getTrailingRequiresClause());
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
- }
- ShouldVisitChildren = false;
- })
- DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
- // This is called for code like 'T()', where T is a template argument.
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
- // These expressions all might take explicit template arguments.
- // We traverse those if so. FIXME: implement these.
- DEF_TRAVERSE_STMT(CXXConstructExpr, {})
- DEF_TRAVERSE_STMT(CallExpr, {})
- DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
- // These exprs (most of them), do not need any action except iterating
- // over the children.
- DEF_TRAVERSE_STMT(AddrLabelExpr, {})
- DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
- DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {})
- DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
- DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
- DEF_TRAVERSE_STMT(OMPIteratorExpr, {})
- DEF_TRAVERSE_STMT(BlockExpr, {
- TRY_TO(TraverseDecl(S->getBlockDecl()));
- return true; // no child statements to loop through.
- })
- DEF_TRAVERSE_STMT(ChooseExpr, {})
- DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
- DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
- DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {
- if (getDerived().shouldVisitImplicitCode())
- TRY_TO(TraverseStmt(S->getExpr()));
- })
- DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
- DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
- DEF_TRAVERSE_STMT(ExprWithCleanups, {})
- DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
- DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
- DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
- DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
- TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
- if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
- TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(CXXThisExpr, {})
- DEF_TRAVERSE_STMT(CXXThrowExpr, {})
- DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
- DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
- DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
- DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
- DEF_TRAVERSE_STMT(GNUNullExpr, {})
- DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
- DEF_TRAVERSE_STMT(NoInitExpr, {})
- DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {
- // FIXME: The source expression of the OVE should be listed as
- // a child of the ArrayInitLoopExpr.
- if (OpaqueValueExpr *OVE = S->getCommonExpr())
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
- })
- DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
- DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
- DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
- if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
- DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
- DEF_TRAVERSE_STMT(ObjCMessageExpr, {
- if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
- TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {
- if (S->isClassReceiver()) {
- ObjCInterfaceDecl *IDecl = S->getClassReceiver();
- QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
- ObjCInterfaceLocInfo Data;
- Data.NameLoc = S->getReceiverLocation();
- Data.NameEndLoc = Data.NameLoc;
- TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
- }
- })
- DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
- DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
- DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
- DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
- DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {})
- DEF_TRAVERSE_STMT(ParenExpr, {})
- DEF_TRAVERSE_STMT(ParenListExpr, {})
- DEF_TRAVERSE_STMT(SYCLUniqueStableNameExpr, {
- TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
- })
- DEF_TRAVERSE_STMT(PredefinedExpr, {})
- DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
- DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
- DEF_TRAVERSE_STMT(StmtExpr, {})
- DEF_TRAVERSE_STMT(SourceLocExpr, {})
- DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
- })
- DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
- TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
- if (S->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
- S->getNumTemplateArgs()));
- }
- })
- DEF_TRAVERSE_STMT(SEHTryStmt, {})
- DEF_TRAVERSE_STMT(SEHExceptStmt, {})
- DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
- DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
- DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
- DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
- DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, {
- if (!getDerived().shouldVisitImplicitCode()) {
- CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
- S->getDecomposedForm();
- TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
- TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
- ShouldVisitChildren = false;
- }
- })
- DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
- DEF_TRAVERSE_STMT(TypoExpr, {})
- DEF_TRAVERSE_STMT(RecoveryExpr, {})
- DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
- // These operators (all of them) do not need any action except
- // iterating over the children.
- DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
- DEF_TRAVERSE_STMT(ConditionalOperator, {})
- DEF_TRAVERSE_STMT(UnaryOperator, {})
- DEF_TRAVERSE_STMT(BinaryOperator, {})
- DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
- DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
- DEF_TRAVERSE_STMT(PackExpansionExpr, {})
- DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
- DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
- DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
- DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
- DEF_TRAVERSE_STMT(CXXFoldExpr, {})
- DEF_TRAVERSE_STMT(AtomicExpr, {})
- DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
- DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
- if (S->getLifetimeExtendedTemporaryDecl()) {
- TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
- S->getLifetimeExtendedTemporaryDecl()));
- ShouldVisitChildren = false;
- }
- })
- // For coroutines expressions, traverse either the operand
- // as written or the implied calls, depending on what the
- // derived class requests.
- DEF_TRAVERSE_STMT(CoroutineBodyStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
- ShouldVisitChildren = false;
- }
- })
- DEF_TRAVERSE_STMT(CoreturnStmt, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- ShouldVisitChildren = false;
- }
- })
- DEF_TRAVERSE_STMT(CoawaitExpr, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- ShouldVisitChildren = false;
- }
- })
- DEF_TRAVERSE_STMT(DependentCoawaitExpr, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- ShouldVisitChildren = false;
- }
- })
- DEF_TRAVERSE_STMT(CoyieldExpr, {
- if (!getDerived().shouldVisitImplicitCode()) {
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
- ShouldVisitChildren = false;
- }
- })
- DEF_TRAVERSE_STMT(ConceptSpecializationExpr,
- { TRY_TO(TraverseConceptReferenceHelper(*S)); })
- DEF_TRAVERSE_STMT(RequiresExpr, {
- TRY_TO(TraverseDecl(S->getBody()));
- for (ParmVarDecl *Parm : S->getLocalParameters())
- TRY_TO(TraverseDecl(Parm));
- for (concepts::Requirement *Req : S->getRequirements())
- TRY_TO(TraverseConceptRequirement(Req));
- })
- // These literals (all of them) do not need any action.
- DEF_TRAVERSE_STMT(IntegerLiteral, {})
- DEF_TRAVERSE_STMT(FixedPointLiteral, {})
- DEF_TRAVERSE_STMT(CharacterLiteral, {})
- DEF_TRAVERSE_STMT(FloatingLiteral, {})
- DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
- DEF_TRAVERSE_STMT(StringLiteral, {})
- DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
- DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
- DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
- DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
- // Traverse OpenCL: AsType, Convert.
- DEF_TRAVERSE_STMT(AsTypeExpr, {})
- // OpenMP directives.
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
- OMPExecutableDirective *S) {
- for (auto *C : S->clauses()) {
- TRY_TO(TraverseOMPClause(C));
- }
- return true;
- }
- DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
- if (!getDerived().shouldVisitImplicitCode()) {
- // Visit only the syntactical loop.
- TRY_TO(TraverseStmt(S->getLoopStmt()));
- ShouldVisitChildren = false;
- }
- })
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
- return TraverseOMPExecutableDirective(S);
- }
- DEF_TRAVERSE_STMT(OMPMetaDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTileDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPUnrollDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPSectionsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPSectionDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPSingleDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPMasterDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPCriticalDirective, {
- TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
- TRY_TO(TraverseOMPExecutableDirective(S));
- })
- DEF_TRAVERSE_STMT(OMPParallelForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTaskDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPBarrierDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPCancelDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPFlushDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPDepobjDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPScanDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPOrderedDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPAtomicDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetDataDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTeamsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPDistributeDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPInteropDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPDispatchDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPMaskedDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- DEF_TRAVERSE_STMT(OMPErrorDirective,
- { TRY_TO(TraverseOMPExecutableDirective(S)); })
- // OpenMP clauses.
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
- if (!C)
- return true;
- switch (C->getClauseKind()) {
- #define GEN_CLANG_CLAUSE_CLASS
- #define CLAUSE_CLASS(Enum, Str, Class) \
- case llvm::omp::Clause::Enum: \
- TRY_TO(Visit##Class(static_cast<Class *>(C))); \
- break;
- #define CLAUSE_NO_CLASS(Enum, Str) \
- case llvm::omp::Clause::Enum: \
- break;
- #include "llvm/Frontend/OpenMP/OMP.inc"
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
- OMPClauseWithPreInit *Node) {
- TRY_TO(TraverseStmt(Node->getPreInitStmt()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
- OMPClauseWithPostUpdate *Node) {
- TRY_TO(VisitOMPClauseWithPreInit(Node));
- TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause(
- OMPAllocatorClause *C) {
- TRY_TO(TraverseStmt(C->getAllocator()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAllocateClause(OMPAllocateClause *C) {
- TRY_TO(TraverseStmt(C->getAllocator()));
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getNumThreads()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAlignClause(OMPAlignClause *C) {
- TRY_TO(TraverseStmt(C->getAlignment()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
- TRY_TO(TraverseStmt(C->getSafelen()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
- TRY_TO(TraverseStmt(C->getSimdlen()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPSizesClause(OMPSizesClause *C) {
- for (Expr *E : C->getSizesRefs())
- TRY_TO(TraverseStmt(E));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
- TRY_TO(TraverseStmt(C->getFactor()));
- return true;
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
- TRY_TO(TraverseStmt(C->getNumForLoops()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
- OMPUnifiedAddressClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedSharedMemoryClause(
- OMPUnifiedSharedMemoryClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPReverseOffloadClause(
- OMPReverseOffloadClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDynamicAllocatorsClause(
- OMPDynamicAllocatorsClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
- OMPAtomicDefaultMemOrderClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPSeverityClause(OMPSeverityClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPMessageClause(OMPMessageClause *C) {
- TRY_TO(TraverseStmt(C->getMessageString()));
- return true;
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getChunkSize()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) {
- TRY_TO(TraverseStmt(C->getNumForLoops()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
- return true;
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAcqRelClause(OMPAcqRelClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAcquireClause(OMPAcquireClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPRelaxedClause(OMPRelaxedClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPInitClause(OMPInitClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUseClause(OMPUseClause *C) {
- TRY_TO(TraverseStmt(C->getInteropVar()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDestroyClause(OMPDestroyClause *C) {
- TRY_TO(TraverseStmt(C->getInteropVar()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPNovariantsClause(
- OMPNovariantsClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPNocontextClause(
- OMPNocontextClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getCondition()));
- return true;
- }
- template <typename Derived>
- template <typename T>
- bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
- for (auto *E : Node->varlists()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause(
- OMPInclusiveClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPExclusiveClause(
- OMPExclusiveClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
- OMPFirstprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- TRY_TO(VisitOMPClauseWithPreInit(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->inits()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
- OMPLastprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- TRY_TO(VisitOMPClauseWithPostUpdate(C));
- for (auto *E : C->private_copies()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
- TRY_TO(TraverseStmt(C->getStep()));
- TRY_TO(TraverseStmt(C->getCalcStep()));
- TRY_TO(VisitOMPClauseList(C));
- TRY_TO(VisitOMPClauseWithPostUpdate(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->inits()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->updates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->finals()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
- TRY_TO(TraverseStmt(C->getAlignment()));
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
- OMPCopyprivateClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->source_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->destination_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->assignment_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
- TRY_TO(VisitOMPClauseList(C));
- TRY_TO(VisitOMPClauseWithPostUpdate(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->lhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->rhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->reduction_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- if (C->getModifier() == OMPC_REDUCTION_inscan) {
- for (auto *E : C->copy_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->copy_array_temps()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->copy_array_elems()) {
- TRY_TO(TraverseStmt(E));
- }
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause(
- OMPTaskReductionClause *C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
- TRY_TO(VisitOMPClauseList(C));
- TRY_TO(VisitOMPClauseWithPostUpdate(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->lhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->rhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->reduction_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPInReductionClause(
- OMPInReductionClause *C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
- TRY_TO(VisitOMPClauseList(C));
- TRY_TO(VisitOMPClauseWithPostUpdate(C));
- for (auto *E : C->privates()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->lhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->rhs_exprs()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->reduction_ops()) {
- TRY_TO(TraverseStmt(E));
- }
- for (auto *E : C->taskgroup_descriptors())
- TRY_TO(TraverseStmt(E));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDepobjClause(OMPDepobjClause *C) {
- TRY_TO(TraverseStmt(C->getDepobj()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getDevice()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
- OMPNumTeamsClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getNumTeams()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
- OMPThreadLimitClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getThreadLimit()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
- OMPPriorityClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getPriority()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
- OMPGrainsizeClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getGrainsize()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause(
- OMPNumTasksClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getNumTasks()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) {
- TRY_TO(TraverseStmt(C->getHint()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDistScheduleClause(
- OMPDistScheduleClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getChunkSize()));
- return true;
- }
- template <typename Derived>
- bool
- RecursiveASTVisitor<Derived>::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPToClause(OMPToClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPFromClause(OMPFromClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUseDevicePtrClause(
- OMPUseDevicePtrClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUseDeviceAddrClause(
- OMPUseDeviceAddrClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause(
- OMPIsDevicePtrClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPHasDeviceAddrClause(
- OMPHasDeviceAddrClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
- OMPNontemporalClause *C) {
- TRY_TO(VisitOMPClauseList(C));
- for (auto *E : C->private_refs()) {
- TRY_TO(TraverseStmt(E));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPOrderClause(OMPOrderClause *) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPDetachClause(OMPDetachClause *C) {
- TRY_TO(TraverseStmt(C->getEventHandler()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPUsesAllocatorsClause(
- OMPUsesAllocatorsClause *C) {
- for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
- const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
- TRY_TO(TraverseStmt(Data.Allocator));
- TRY_TO(TraverseStmt(Data.AllocatorTraits));
- }
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause(
- OMPAffinityClause *C) {
- TRY_TO(TraverseStmt(C->getModifier()));
- for (Expr *E : C->varlists())
- TRY_TO(TraverseStmt(E));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPFilterClause(OMPFilterClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getThreadID()));
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPBindClause(OMPBindClause *C) {
- return true;
- }
- template <typename Derived>
- bool RecursiveASTVisitor<Derived>::VisitOMPXDynCGroupMemClause(
- OMPXDynCGroupMemClause *C) {
- TRY_TO(VisitOMPClauseWithPreInit(C));
- TRY_TO(TraverseStmt(C->getSize()));
- return true;
- }
- // FIXME: look at the following tricky-seeming exprs to see if we
- // need to recurse on anything. These are ones that have methods
- // returning decls or qualtypes or nestednamespecifier -- though I'm
- // not sure if they own them -- or just seemed very complicated, or
- // had lots of sub-types to explore.
- //
- // VisitOverloadExpr and its children: recurse on template args? etc?
- // FIXME: go through all the stmts and exprs again, and see which of them
- // create new types, and recurse on the types (TypeLocs?) of those.
- // Candidates:
- //
- // http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
- // http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
- // http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
- // Every class that has getQualifier.
- #undef DEF_TRAVERSE_STMT
- #undef TRAVERSE_STMT
- #undef TRAVERSE_STMT_BASE
- #undef TRY_TO
- } // end namespace clang
- #endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|