123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- Parser.h - C Language Parser ---------------------------*- 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 Parser interface.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_PARSE_PARSER_H
- #define LLVM_CLANG_PARSE_PARSER_H
- #include "clang/AST/Availability.h"
- #include "clang/Basic/BitmaskEnum.h"
- #include "clang/Basic/OpenMPKinds.h"
- #include "clang/Basic/OperatorPrecedence.h"
- #include "clang/Basic/Specifiers.h"
- #include "clang/Lex/CodeCompletionHandler.h"
- #include "clang/Lex/Preprocessor.h"
- #include "clang/Sema/DeclSpec.h"
- #include "clang/Sema/Sema.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/Frontend/OpenMP/OMPContext.h"
- #include "llvm/Support/Compiler.h"
- #include "llvm/Support/PrettyStackTrace.h"
- #include "llvm/Support/SaveAndRestore.h"
- #include <memory>
- #include <stack>
- namespace clang {
- class PragmaHandler;
- class Scope;
- class BalancedDelimiterTracker;
- class CorrectionCandidateCallback;
- class DeclGroupRef;
- class DiagnosticBuilder;
- struct LoopHint;
- class Parser;
- class ParsingDeclRAIIObject;
- class ParsingDeclSpec;
- class ParsingDeclarator;
- class ParsingFieldDeclarator;
- class ColonProtectionRAIIObject;
- class InMessageExpressionRAIIObject;
- class PoisonSEHIdentifiersRAIIObject;
- class OMPClause;
- class ObjCTypeParamList;
- struct OMPTraitProperty;
- struct OMPTraitSelector;
- struct OMPTraitSet;
- class OMPTraitInfo;
- /// Parser - This implements a parser for the C family of languages. After
- /// parsing units of the grammar, productions are invoked to handle whatever has
- /// been read.
- ///
- class Parser : public CodeCompletionHandler {
- friend class ColonProtectionRAIIObject;
- friend class ParsingOpenMPDirectiveRAII;
- friend class InMessageExpressionRAIIObject;
- friend class PoisonSEHIdentifiersRAIIObject;
- friend class ObjCDeclContextSwitch;
- friend class ParenBraceBracketBalancer;
- friend class BalancedDelimiterTracker;
- Preprocessor &PP;
- /// Tok - The current token we are peeking ahead. All parsing methods assume
- /// that this is valid.
- Token Tok;
- // PrevTokLocation - The location of the token we previously
- // consumed. This token is used for diagnostics where we expected to
- // see a token following another token (e.g., the ';' at the end of
- // a statement).
- SourceLocation PrevTokLocation;
- /// Tracks an expected type for the current token when parsing an expression.
- /// Used by code completion for ranking.
- PreferredTypeBuilder PreferredType;
- unsigned short ParenCount = 0, BracketCount = 0, BraceCount = 0;
- unsigned short MisplacedModuleBeginCount = 0;
- /// Actions - These are the callbacks we invoke as we parse various constructs
- /// in the file.
- Sema &Actions;
- DiagnosticsEngine &Diags;
- /// ScopeCache - Cache scopes to reduce malloc traffic.
- enum { ScopeCacheSize = 16 };
- unsigned NumCachedScopes;
- Scope *ScopeCache[ScopeCacheSize];
- /// Identifiers used for SEH handling in Borland. These are only
- /// allowed in particular circumstances
- // __except block
- IdentifierInfo *Ident__exception_code,
- *Ident___exception_code,
- *Ident_GetExceptionCode;
- // __except filter expression
- IdentifierInfo *Ident__exception_info,
- *Ident___exception_info,
- *Ident_GetExceptionInfo;
- // __finally
- IdentifierInfo *Ident__abnormal_termination,
- *Ident___abnormal_termination,
- *Ident_AbnormalTermination;
- /// Contextual keywords for Microsoft extensions.
- IdentifierInfo *Ident__except;
- mutable IdentifierInfo *Ident_sealed;
- mutable IdentifierInfo *Ident_abstract;
- /// Ident_super - IdentifierInfo for "super", to support fast
- /// comparison.
- IdentifierInfo *Ident_super;
- /// Ident_vector, Ident_bool, Ident_Bool - cached IdentifierInfos for "vector"
- /// and "bool" fast comparison. Only present if AltiVec or ZVector are
- /// enabled.
- IdentifierInfo *Ident_vector;
- IdentifierInfo *Ident_bool;
- IdentifierInfo *Ident_Bool;
- /// Ident_pixel - cached IdentifierInfos for "pixel" fast comparison.
- /// Only present if AltiVec enabled.
- IdentifierInfo *Ident_pixel;
- /// Objective-C contextual keywords.
- IdentifierInfo *Ident_instancetype;
- /// Identifier for "introduced".
- IdentifierInfo *Ident_introduced;
- /// Identifier for "deprecated".
- IdentifierInfo *Ident_deprecated;
- /// Identifier for "obsoleted".
- IdentifierInfo *Ident_obsoleted;
- /// Identifier for "unavailable".
- IdentifierInfo *Ident_unavailable;
- /// Identifier for "message".
- IdentifierInfo *Ident_message;
- /// Identifier for "strict".
- IdentifierInfo *Ident_strict;
- /// Identifier for "replacement".
- IdentifierInfo *Ident_replacement;
- /// Identifiers used by the 'external_source_symbol' attribute.
- IdentifierInfo *Ident_language, *Ident_defined_in,
- *Ident_generated_declaration;
- /// C++11 contextual keywords.
- mutable IdentifierInfo *Ident_final;
- mutable IdentifierInfo *Ident_GNU_final;
- mutable IdentifierInfo *Ident_override;
- // C++2a contextual keywords.
- mutable IdentifierInfo *Ident_import;
- mutable IdentifierInfo *Ident_module;
- // C++ type trait keywords that can be reverted to identifiers and still be
- // used as type traits.
- llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
- std::unique_ptr<PragmaHandler> AlignHandler;
- std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
- std::unique_ptr<PragmaHandler> OptionsHandler;
- std::unique_ptr<PragmaHandler> PackHandler;
- std::unique_ptr<PragmaHandler> MSStructHandler;
- std::unique_ptr<PragmaHandler> UnusedHandler;
- std::unique_ptr<PragmaHandler> WeakHandler;
- std::unique_ptr<PragmaHandler> RedefineExtnameHandler;
- std::unique_ptr<PragmaHandler> FPContractHandler;
- std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
- std::unique_ptr<PragmaHandler> OpenMPHandler;
- std::unique_ptr<PragmaHandler> PCSectionHandler;
- std::unique_ptr<PragmaHandler> MSCommentHandler;
- std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
- std::unique_ptr<PragmaHandler> FloatControlHandler;
- std::unique_ptr<PragmaHandler> MSPointersToMembers;
- std::unique_ptr<PragmaHandler> MSVtorDisp;
- std::unique_ptr<PragmaHandler> MSInitSeg;
- std::unique_ptr<PragmaHandler> MSDataSeg;
- std::unique_ptr<PragmaHandler> MSBSSSeg;
- std::unique_ptr<PragmaHandler> MSConstSeg;
- std::unique_ptr<PragmaHandler> MSCodeSeg;
- std::unique_ptr<PragmaHandler> MSSection;
- std::unique_ptr<PragmaHandler> MSRuntimeChecks;
- std::unique_ptr<PragmaHandler> MSIntrinsic;
- std::unique_ptr<PragmaHandler> MSOptimize;
- std::unique_ptr<PragmaHandler> MSFenvAccess;
- std::unique_ptr<PragmaHandler> CUDAForceHostDeviceHandler;
- std::unique_ptr<PragmaHandler> OptimizeHandler;
- std::unique_ptr<PragmaHandler> LoopHintHandler;
- std::unique_ptr<PragmaHandler> UnrollHintHandler;
- std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
- std::unique_ptr<PragmaHandler> UnrollAndJamHintHandler;
- std::unique_ptr<PragmaHandler> NoUnrollAndJamHintHandler;
- std::unique_ptr<PragmaHandler> FPHandler;
- std::unique_ptr<PragmaHandler> STDCFenvAccessHandler;
- std::unique_ptr<PragmaHandler> STDCFenvRoundHandler;
- std::unique_ptr<PragmaHandler> STDCCXLIMITHandler;
- std::unique_ptr<PragmaHandler> STDCUnknownHandler;
- std::unique_ptr<PragmaHandler> AttributePragmaHandler;
- std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
- std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
- std::unique_ptr<CommentHandler> CommentSemaHandler;
- /// Whether the '>' token acts as an operator or not. This will be
- /// true except when we are parsing an expression within a C++
- /// template argument list, where the '>' closes the template
- /// argument list.
- bool GreaterThanIsOperator;
- /// ColonIsSacred - When this is false, we aggressively try to recover from
- /// code like "foo : bar" as if it were a typo for "foo :: bar". This is not
- /// safe in case statements and a few other things. This is managed by the
- /// ColonProtectionRAIIObject RAII object.
- bool ColonIsSacred;
- /// Parsing OpenMP directive mode.
- bool OpenMPDirectiveParsing = false;
- /// When true, we are directly inside an Objective-C message
- /// send expression.
- ///
- /// This is managed by the \c InMessageExpressionRAIIObject class, and
- /// should not be set directly.
- bool InMessageExpression;
- /// Gets set to true after calling ProduceSignatureHelp, it is for a
- /// workaround to make sure ProduceSignatureHelp is only called at the deepest
- /// function call.
- bool CalledSignatureHelp = false;
- /// The "depth" of the template parameters currently being parsed.
- unsigned TemplateParameterDepth;
- /// Current kind of OpenMP clause
- OpenMPClauseKind OMPClauseKind = llvm::omp::OMPC_unknown;
- /// RAII class that manages the template parameter depth.
- class TemplateParameterDepthRAII {
- unsigned &Depth;
- unsigned AddedLevels;
- public:
- explicit TemplateParameterDepthRAII(unsigned &Depth)
- : Depth(Depth), AddedLevels(0) {}
- ~TemplateParameterDepthRAII() {
- Depth -= AddedLevels;
- }
- void operator++() {
- ++Depth;
- ++AddedLevels;
- }
- void addDepth(unsigned D) {
- Depth += D;
- AddedLevels += D;
- }
- void setAddedDepth(unsigned D) {
- Depth = Depth - AddedLevels + D;
- AddedLevels = D;
- }
- unsigned getDepth() const { return Depth; }
- unsigned getOriginalDepth() const { return Depth - AddedLevels; }
- };
- /// Factory object for creating ParsedAttr objects.
- AttributeFactory AttrFactory;
- /// Gathers and cleans up TemplateIdAnnotations when parsing of a
- /// top-level declaration is finished.
- SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
- void MaybeDestroyTemplateIds() {
- if (!TemplateIds.empty() &&
- (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens()))
- DestroyTemplateIds();
- }
- void DestroyTemplateIds();
- /// RAII object to destroy TemplateIdAnnotations where possible, from a
- /// likely-good position during parsing.
- struct DestroyTemplateIdAnnotationsRAIIObj {
- Parser &Self;
- DestroyTemplateIdAnnotationsRAIIObj(Parser &Self) : Self(Self) {}
- ~DestroyTemplateIdAnnotationsRAIIObj() { Self.MaybeDestroyTemplateIds(); }
- };
- /// Identifiers which have been declared within a tentative parse.
- SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
- /// Tracker for '<' tokens that might have been intended to be treated as an
- /// angle bracket instead of a less-than comparison.
- ///
- /// This happens when the user intends to form a template-id, but typoes the
- /// template-name or forgets a 'template' keyword for a dependent template
- /// name.
- ///
- /// We track these locations from the point where we see a '<' with a
- /// name-like expression on its left until we see a '>' or '>>' that might
- /// match it.
- struct AngleBracketTracker {
- /// Flags used to rank candidate template names when there is more than one
- /// '<' in a scope.
- enum Priority : unsigned short {
- /// A non-dependent name that is a potential typo for a template name.
- PotentialTypo = 0x0,
- /// A dependent name that might instantiate to a template-name.
- DependentName = 0x2,
- /// A space appears before the '<' token.
- SpaceBeforeLess = 0x0,
- /// No space before the '<' token
- NoSpaceBeforeLess = 0x1,
- LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ DependentName)
- };
- struct Loc {
- Expr *TemplateName;
- SourceLocation LessLoc;
- AngleBracketTracker::Priority Priority;
- unsigned short ParenCount, BracketCount, BraceCount;
- bool isActive(Parser &P) const {
- return P.ParenCount == ParenCount && P.BracketCount == BracketCount &&
- P.BraceCount == BraceCount;
- }
- bool isActiveOrNested(Parser &P) const {
- return isActive(P) || P.ParenCount > ParenCount ||
- P.BracketCount > BracketCount || P.BraceCount > BraceCount;
- }
- };
- SmallVector<Loc, 8> Locs;
- /// Add an expression that might have been intended to be a template name.
- /// In the case of ambiguity, we arbitrarily select the innermost such
- /// expression, for example in 'foo < bar < baz', 'bar' is the current
- /// candidate. No attempt is made to track that 'foo' is also a candidate
- /// for the case where we see a second suspicious '>' token.
- void add(Parser &P, Expr *TemplateName, SourceLocation LessLoc,
- Priority Prio) {
- if (!Locs.empty() && Locs.back().isActive(P)) {
- if (Locs.back().Priority <= Prio) {
- Locs.back().TemplateName = TemplateName;
- Locs.back().LessLoc = LessLoc;
- Locs.back().Priority = Prio;
- }
- } else {
- Locs.push_back({TemplateName, LessLoc, Prio,
- P.ParenCount, P.BracketCount, P.BraceCount});
- }
- }
- /// Mark the current potential missing template location as having been
- /// handled (this happens if we pass a "corresponding" '>' or '>>' token
- /// or leave a bracket scope).
- void clear(Parser &P) {
- while (!Locs.empty() && Locs.back().isActiveOrNested(P))
- Locs.pop_back();
- }
- /// Get the current enclosing expression that might hve been intended to be
- /// a template name.
- Loc *getCurrent(Parser &P) {
- if (!Locs.empty() && Locs.back().isActive(P))
- return &Locs.back();
- return nullptr;
- }
- };
- AngleBracketTracker AngleBrackets;
- IdentifierInfo *getSEHExceptKeyword();
- /// True if we are within an Objective-C container while parsing C-like decls.
- ///
- /// This is necessary because Sema thinks we have left the container
- /// to parse the C-like decls, meaning Actions.getObjCDeclContext() will
- /// be NULL.
- bool ParsingInObjCContainer;
- /// Whether to skip parsing of function bodies.
- ///
- /// This option can be used, for example, to speed up searches for
- /// declarations/definitions when indexing.
- bool SkipFunctionBodies;
- /// The location of the expression statement that is being parsed right now.
- /// Used to determine if an expression that is being parsed is a statement or
- /// just a regular sub-expression.
- SourceLocation ExprStatementTokLoc;
- /// Flags describing a context in which we're parsing a statement.
- enum class ParsedStmtContext {
- /// This context permits declarations in language modes where declarations
- /// are not statements.
- AllowDeclarationsInC = 0x1,
- /// This context permits standalone OpenMP directives.
- AllowStandaloneOpenMPDirectives = 0x2,
- /// This context is at the top level of a GNU statement expression.
- InStmtExpr = 0x4,
- /// The context of a regular substatement.
- SubStmt = 0,
- /// The context of a compound-statement.
- Compound = AllowDeclarationsInC | AllowStandaloneOpenMPDirectives,
- LLVM_MARK_AS_BITMASK_ENUM(InStmtExpr)
- };
- /// Act on an expression statement that might be the last statement in a
- /// GNU statement expression. Checks whether we are actually at the end of
- /// a statement expression and builds a suitable expression statement.
- StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx);
- public:
- Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
- ~Parser() override;
- const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
- const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
- Preprocessor &getPreprocessor() const { return PP; }
- Sema &getActions() const { return Actions; }
- AttributeFactory &getAttrFactory() { return AttrFactory; }
- const Token &getCurToken() const { return Tok; }
- Scope *getCurScope() const { return Actions.getCurScope(); }
- void incrementMSManglingNumber() const {
- return Actions.incrementMSManglingNumber();
- }
- Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
- // Type forwarding. All of these are statically 'void*', but they may all be
- // different actual classes based on the actions in place.
- typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
- typedef OpaquePtr<TemplateName> TemplateTy;
- typedef SmallVector<TemplateParameterList *, 4> TemplateParameterLists;
- typedef Sema::FullExprArg FullExprArg;
- // Parsing methods.
- /// Initialize - Warm up the parser.
- ///
- void Initialize();
- /// Parse the first top-level declaration in a translation unit.
- bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result);
- /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
- /// the EOF was encountered.
- bool ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl = false);
- bool ParseTopLevelDecl() {
- DeclGroupPtrTy Result;
- return ParseTopLevelDecl(Result);
- }
- /// ConsumeToken - Consume the current 'peek token' and lex the next one.
- /// This does not work with special tokens: string literals, code completion,
- /// annotation tokens and balanced tokens must be handled using the specific
- /// consume methods.
- /// Returns the location of the consumed token.
- SourceLocation ConsumeToken() {
- assert(!isTokenSpecial() &&
- "Should consume special tokens with Consume*Token");
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
- bool TryConsumeToken(tok::TokenKind Expected) {
- if (Tok.isNot(Expected))
- return false;
- assert(!isTokenSpecial() &&
- "Should consume special tokens with Consume*Token");
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return true;
- }
- bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
- if (!TryConsumeToken(Expected))
- return false;
- Loc = PrevTokLocation;
- return true;
- }
- /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
- /// current token type. This should only be used in cases where the type of
- /// the token really isn't known, e.g. in error recovery.
- SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
- if (isTokenParen())
- return ConsumeParen();
- if (isTokenBracket())
- return ConsumeBracket();
- if (isTokenBrace())
- return ConsumeBrace();
- if (isTokenStringLiteral())
- return ConsumeStringToken();
- if (Tok.is(tok::code_completion))
- return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
- : handleUnexpectedCodeCompletionToken();
- if (Tok.isAnnotation())
- return ConsumeAnnotationToken();
- return ConsumeToken();
- }
- SourceLocation getEndOfPreviousToken() {
- return PP.getLocForEndOfToken(PrevTokLocation);
- }
- /// Retrieve the underscored keyword (_Nonnull, _Nullable) that corresponds
- /// to the given nullability kind.
- IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability) {
- return Actions.getNullabilityKeyword(nullability);
- }
- private:
- //===--------------------------------------------------------------------===//
- // Low-Level token peeking and consumption methods.
- //
- /// isTokenParen - Return true if the cur token is '(' or ')'.
- bool isTokenParen() const {
- return Tok.isOneOf(tok::l_paren, tok::r_paren);
- }
- /// isTokenBracket - Return true if the cur token is '[' or ']'.
- bool isTokenBracket() const {
- return Tok.isOneOf(tok::l_square, tok::r_square);
- }
- /// isTokenBrace - Return true if the cur token is '{' or '}'.
- bool isTokenBrace() const {
- return Tok.isOneOf(tok::l_brace, tok::r_brace);
- }
- /// isTokenStringLiteral - True if this token is a string-literal.
- bool isTokenStringLiteral() const {
- return tok::isStringLiteral(Tok.getKind());
- }
- /// isTokenSpecial - True if this token requires special consumption methods.
- bool isTokenSpecial() const {
- return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
- isTokenBrace() || Tok.is(tok::code_completion) || Tok.isAnnotation();
- }
- /// Returns true if the current token is '=' or is a type of '='.
- /// For typos, give a fixit to '='
- bool isTokenEqualOrEqualTypo();
- /// Return the current token to the token stream and make the given
- /// token the current token.
- void UnconsumeToken(Token &Consumed) {
- Token Next = Tok;
- PP.EnterToken(Consumed, /*IsReinject*/true);
- PP.Lex(Tok);
- PP.EnterToken(Next, /*IsReinject*/true);
- }
- SourceLocation ConsumeAnnotationToken() {
- assert(Tok.isAnnotation() && "wrong consume method");
- SourceLocation Loc = Tok.getLocation();
- PrevTokLocation = Tok.getAnnotationEndLoc();
- PP.Lex(Tok);
- return Loc;
- }
- /// ConsumeParen - This consume method keeps the paren count up-to-date.
- ///
- SourceLocation ConsumeParen() {
- assert(isTokenParen() && "wrong consume method");
- if (Tok.getKind() == tok::l_paren)
- ++ParenCount;
- else if (ParenCount) {
- AngleBrackets.clear(*this);
- --ParenCount; // Don't let unbalanced )'s drive the count negative.
- }
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
- /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
- ///
- SourceLocation ConsumeBracket() {
- assert(isTokenBracket() && "wrong consume method");
- if (Tok.getKind() == tok::l_square)
- ++BracketCount;
- else if (BracketCount) {
- AngleBrackets.clear(*this);
- --BracketCount; // Don't let unbalanced ]'s drive the count negative.
- }
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
- /// ConsumeBrace - This consume method keeps the brace count up-to-date.
- ///
- SourceLocation ConsumeBrace() {
- assert(isTokenBrace() && "wrong consume method");
- if (Tok.getKind() == tok::l_brace)
- ++BraceCount;
- else if (BraceCount) {
- AngleBrackets.clear(*this);
- --BraceCount; // Don't let unbalanced }'s drive the count negative.
- }
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
- /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
- /// and returning the token kind. This method is specific to strings, as it
- /// handles string literal concatenation, as per C99 5.1.1.2, translation
- /// phase #6.
- SourceLocation ConsumeStringToken() {
- assert(isTokenStringLiteral() &&
- "Should only consume string literals with this method");
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
- /// Consume the current code-completion token.
- ///
- /// This routine can be called to consume the code-completion token and
- /// continue processing in special cases where \c cutOffParsing() isn't
- /// desired, such as token caching or completion with lookahead.
- SourceLocation ConsumeCodeCompletionToken() {
- assert(Tok.is(tok::code_completion));
- PrevTokLocation = Tok.getLocation();
- PP.Lex(Tok);
- return PrevTokLocation;
- }
- ///\ brief When we are consuming a code-completion token without having
- /// matched specific position in the grammar, provide code-completion results
- /// based on context.
- ///
- /// \returns the source location of the code-completion token.
- SourceLocation handleUnexpectedCodeCompletionToken();
- /// Abruptly cut off parsing; mainly used when we have reached the
- /// code-completion point.
- void cutOffParsing() {
- if (PP.isCodeCompletionEnabled())
- PP.setCodeCompletionReached();
- // Cut off parsing by acting as if we reached the end-of-file.
- Tok.setKind(tok::eof);
- }
- /// Determine if we're at the end of the file or at a transition
- /// between modules.
- bool isEofOrEom() {
- tok::TokenKind Kind = Tok.getKind();
- return Kind == tok::eof || Kind == tok::annot_module_begin ||
- Kind == tok::annot_module_end || Kind == tok::annot_module_include;
- }
- /// Checks if the \p Level is valid for use in a fold expression.
- bool isFoldOperator(prec::Level Level) const;
- /// Checks if the \p Kind is a valid operator for fold expressions.
- bool isFoldOperator(tok::TokenKind Kind) const;
- /// Initialize all pragma handlers.
- void initializePragmaHandlers();
- /// Destroy and reset all pragma handlers.
- void resetPragmaHandlers();
- /// Handle the annotation token produced for #pragma unused(...)
- void HandlePragmaUnused();
- /// Handle the annotation token produced for
- /// #pragma GCC visibility...
- void HandlePragmaVisibility();
- /// Handle the annotation token produced for
- /// #pragma pack...
- void HandlePragmaPack();
- /// Handle the annotation token produced for
- /// #pragma ms_struct...
- void HandlePragmaMSStruct();
- void HandlePragmaMSPointersToMembers();
- void HandlePragmaMSVtorDisp();
- void HandlePragmaMSPragma();
- bool HandlePragmaMSSection(StringRef PragmaName,
- SourceLocation PragmaLocation);
- bool HandlePragmaMSSegment(StringRef PragmaName,
- SourceLocation PragmaLocation);
- bool HandlePragmaMSInitSeg(StringRef PragmaName,
- SourceLocation PragmaLocation);
- /// Handle the annotation token produced for
- /// #pragma align...
- void HandlePragmaAlign();
- /// Handle the annotation token produced for
- /// #pragma clang __debug dump...
- void HandlePragmaDump();
- /// Handle the annotation token produced for
- /// #pragma weak id...
- void HandlePragmaWeak();
- /// Handle the annotation token produced for
- /// #pragma weak id = id...
- void HandlePragmaWeakAlias();
- /// Handle the annotation token produced for
- /// #pragma redefine_extname...
- void HandlePragmaRedefineExtname();
- /// Handle the annotation token produced for
- /// #pragma STDC FP_CONTRACT...
- void HandlePragmaFPContract();
- /// Handle the annotation token produced for
- /// #pragma STDC FENV_ACCESS...
- void HandlePragmaFEnvAccess();
- /// Handle the annotation token produced for
- /// #pragma STDC FENV_ROUND...
- void HandlePragmaFEnvRound();
- /// Handle the annotation token produced for
- /// #pragma float_control
- void HandlePragmaFloatControl();
- /// \brief Handle the annotation token produced for
- /// #pragma clang fp ...
- void HandlePragmaFP();
- /// Handle the annotation token produced for
- /// #pragma OPENCL EXTENSION...
- void HandlePragmaOpenCLExtension();
- /// Handle the annotation token produced for
- /// #pragma clang __debug captured
- StmtResult HandlePragmaCaptured();
- /// Handle the annotation token produced for
- /// #pragma clang loop and #pragma unroll.
- bool HandlePragmaLoopHint(LoopHint &Hint);
- bool ParsePragmaAttributeSubjectMatchRuleSet(
- attr::ParsedSubjectMatchRuleSet &SubjectMatchRules,
- SourceLocation &AnyLoc, SourceLocation &LastMatchRuleEndLoc);
- void HandlePragmaAttribute();
- /// GetLookAheadToken - This peeks ahead N tokens and returns that token
- /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
- /// returns the token after Tok, etc.
- ///
- /// Note that this differs from the Preprocessor's LookAhead method, because
- /// the Parser always has one token lexed that the preprocessor doesn't.
- ///
- const Token &GetLookAheadToken(unsigned N) {
- if (N == 0 || Tok.is(tok::eof)) return Tok;
- return PP.LookAhead(N-1);
- }
- public:
- /// NextToken - This peeks ahead one token and returns it without
- /// consuming it.
- const Token &NextToken() {
- return PP.LookAhead(0);
- }
- /// getTypeAnnotation - Read a parsed type out of an annotation token.
- static TypeResult getTypeAnnotation(const Token &Tok) {
- if (!Tok.getAnnotationValue())
- return TypeError();
- return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
- }
- private:
- static void setTypeAnnotation(Token &Tok, TypeResult T) {
- assert((T.isInvalid() || T.get()) &&
- "produced a valid-but-null type annotation?");
- Tok.setAnnotationValue(T.isInvalid() ? nullptr : T.get().getAsOpaquePtr());
- }
- static NamedDecl *getNonTypeAnnotation(const Token &Tok) {
- return static_cast<NamedDecl*>(Tok.getAnnotationValue());
- }
- static void setNonTypeAnnotation(Token &Tok, NamedDecl *ND) {
- Tok.setAnnotationValue(ND);
- }
- static IdentifierInfo *getIdentifierAnnotation(const Token &Tok) {
- return static_cast<IdentifierInfo*>(Tok.getAnnotationValue());
- }
- static void setIdentifierAnnotation(Token &Tok, IdentifierInfo *ND) {
- Tok.setAnnotationValue(ND);
- }
- /// Read an already-translated primary expression out of an annotation
- /// token.
- static ExprResult getExprAnnotation(const Token &Tok) {
- return ExprResult::getFromOpaquePointer(Tok.getAnnotationValue());
- }
- /// Set the primary expression corresponding to the given annotation
- /// token.
- static void setExprAnnotation(Token &Tok, ExprResult ER) {
- Tok.setAnnotationValue(ER.getAsOpaquePointer());
- }
- public:
- // If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to
- // find a type name by attempting typo correction.
- bool TryAnnotateTypeOrScopeToken();
- bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
- bool IsNewScope);
- bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
- bool MightBeCXXScopeToken() {
- return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
- (Tok.is(tok::annot_template_id) &&
- NextToken().is(tok::coloncolon)) ||
- Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
- }
- bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
- return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
- }
- private:
- enum AnnotatedNameKind {
- /// Annotation has failed and emitted an error.
- ANK_Error,
- /// The identifier is a tentatively-declared name.
- ANK_TentativeDecl,
- /// The identifier is a template name. FIXME: Add an annotation for that.
- ANK_TemplateName,
- /// The identifier can't be resolved.
- ANK_Unresolved,
- /// Annotation was successful.
- ANK_Success
- };
- AnnotatedNameKind TryAnnotateName(CorrectionCandidateCallback *CCC = nullptr);
- /// Push a tok::annot_cxxscope token onto the token stream.
- void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
- /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
- /// replacing them with the non-context-sensitive keywords. This returns
- /// true if the token was replaced.
- bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- bool &isInvalid) {
- if (!getLangOpts().AltiVec && !getLangOpts().ZVector)
- return false;
- if (Tok.getIdentifierInfo() != Ident_vector &&
- Tok.getIdentifierInfo() != Ident_bool &&
- Tok.getIdentifierInfo() != Ident_Bool &&
- (!getLangOpts().AltiVec || Tok.getIdentifierInfo() != Ident_pixel))
- return false;
- return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid);
- }
- /// TryAltiVecVectorToken - Check for context-sensitive AltiVec vector
- /// identifier token, replacing it with the non-context-sensitive __vector.
- /// This returns true if the token was replaced.
- bool TryAltiVecVectorToken() {
- if ((!getLangOpts().AltiVec && !getLangOpts().ZVector) ||
- Tok.getIdentifierInfo() != Ident_vector) return false;
- return TryAltiVecVectorTokenOutOfLine();
- }
- bool TryAltiVecVectorTokenOutOfLine();
- bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
- const char *&PrevSpec, unsigned &DiagID,
- bool &isInvalid);
- /// Returns true if the current token is the identifier 'instancetype'.
- ///
- /// Should only be used in Objective-C language modes.
- bool isObjCInstancetype() {
- assert(getLangOpts().ObjC);
- if (Tok.isAnnotation())
- return false;
- if (!Ident_instancetype)
- Ident_instancetype = PP.getIdentifierInfo("instancetype");
- return Tok.getIdentifierInfo() == Ident_instancetype;
- }
- /// TryKeywordIdentFallback - For compatibility with system headers using
- /// keywords as identifiers, attempt to convert the current token to an
- /// identifier and optionally disable the keyword for the remainder of the
- /// translation unit. This returns false if the token was not replaced,
- /// otherwise emits a diagnostic and returns true.
- bool TryKeywordIdentFallback(bool DisableKeyword);
- /// Get the TemplateIdAnnotation from the token.
- TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
- /// TentativeParsingAction - An object that is used as a kind of "tentative
- /// parsing transaction". It gets instantiated to mark the token position and
- /// after the token consumption is done, Commit() or Revert() is called to
- /// either "commit the consumed tokens" or revert to the previously marked
- /// token position. Example:
- ///
- /// TentativeParsingAction TPA(*this);
- /// ConsumeToken();
- /// ....
- /// TPA.Revert();
- ///
- class TentativeParsingAction {
- Parser &P;
- PreferredTypeBuilder PrevPreferredType;
- Token PrevTok;
- size_t PrevTentativelyDeclaredIdentifierCount;
- unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
- bool isActive;
- public:
- explicit TentativeParsingAction(Parser &p)
- : P(p), PrevPreferredType(P.PreferredType) {
- PrevTok = P.Tok;
- PrevTentativelyDeclaredIdentifierCount =
- P.TentativelyDeclaredIdentifiers.size();
- PrevParenCount = P.ParenCount;
- PrevBracketCount = P.BracketCount;
- PrevBraceCount = P.BraceCount;
- P.PP.EnableBacktrackAtThisPos();
- isActive = true;
- }
- void Commit() {
- assert(isActive && "Parsing action was finished!");
- P.TentativelyDeclaredIdentifiers.resize(
- PrevTentativelyDeclaredIdentifierCount);
- P.PP.CommitBacktrackedTokens();
- isActive = false;
- }
- void Revert() {
- assert(isActive && "Parsing action was finished!");
- P.PP.Backtrack();
- P.PreferredType = PrevPreferredType;
- P.Tok = PrevTok;
- P.TentativelyDeclaredIdentifiers.resize(
- PrevTentativelyDeclaredIdentifierCount);
- P.ParenCount = PrevParenCount;
- P.BracketCount = PrevBracketCount;
- P.BraceCount = PrevBraceCount;
- isActive = false;
- }
- ~TentativeParsingAction() {
- assert(!isActive && "Forgot to call Commit or Revert!");
- }
- };
- /// A TentativeParsingAction that automatically reverts in its destructor.
- /// Useful for disambiguation parses that will always be reverted.
- class RevertingTentativeParsingAction
- : private Parser::TentativeParsingAction {
- public:
- RevertingTentativeParsingAction(Parser &P)
- : Parser::TentativeParsingAction(P) {}
- ~RevertingTentativeParsingAction() { Revert(); }
- };
- class UnannotatedTentativeParsingAction;
- /// ObjCDeclContextSwitch - An object used to switch context from
- /// an objective-c decl context to its enclosing decl context and
- /// back.
- class ObjCDeclContextSwitch {
- Parser &P;
- Decl *DC;
- SaveAndRestore<bool> WithinObjCContainer;
- public:
- explicit ObjCDeclContextSwitch(Parser &p)
- : P(p), DC(p.getObjCDeclContext()),
- WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
- if (DC)
- P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC));
- }
- ~ObjCDeclContextSwitch() {
- if (DC)
- P.Actions.ActOnObjCReenterContainerContext(cast<DeclContext>(DC));
- }
- };
- /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
- /// input. If so, it is consumed and false is returned.
- ///
- /// If a trivial punctuator misspelling is encountered, a FixIt error
- /// diagnostic is issued and false is returned after recovery.
- ///
- /// If the input is malformed, this emits the specified diagnostic and true is
- /// returned.
- bool ExpectAndConsume(tok::TokenKind ExpectedTok,
- unsigned Diag = diag::err_expected,
- StringRef DiagMsg = "");
- /// The parser expects a semicolon and, if present, will consume it.
- ///
- /// If the next token is not a semicolon, this emits the specified diagnostic,
- /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
- /// to the semicolon, consumes that extra token.
- bool ExpectAndConsumeSemi(unsigned DiagID);
- /// The kind of extra semi diagnostic to emit.
- enum ExtraSemiKind {
- OutsideFunction = 0,
- InsideStruct = 1,
- InstanceVariableList = 2,
- AfterMemberFunctionDefinition = 3
- };
- /// Consume any extra semi-colons until the end of the line.
- void ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST T = TST_unspecified);
- /// Return false if the next token is an identifier. An 'expected identifier'
- /// error is emitted otherwise.
- ///
- /// The parser tries to recover from the error by checking if the next token
- /// is a C++ keyword when parsing Objective-C++. Return false if the recovery
- /// was successful.
- bool expectIdentifier();
- /// Kinds of compound pseudo-tokens formed by a sequence of two real tokens.
- enum class CompoundToken {
- /// A '(' '{' beginning a statement-expression.
- StmtExprBegin,
- /// A '}' ')' ending a statement-expression.
- StmtExprEnd,
- /// A '[' '[' beginning a C++11 or C2x attribute.
- AttrBegin,
- /// A ']' ']' ending a C++11 or C2x attribute.
- AttrEnd,
- /// A '::' '*' forming a C++ pointer-to-member declaration.
- MemberPtr,
- };
- /// Check that a compound operator was written in a "sensible" way, and warn
- /// if not.
- void checkCompoundToken(SourceLocation FirstTokLoc,
- tok::TokenKind FirstTokKind, CompoundToken Op);
- public:
- //===--------------------------------------------------------------------===//
- // Scope manipulation
- /// ParseScope - Introduces a new scope for parsing. The kind of
- /// scope is determined by ScopeFlags. Objects of this type should
- /// be created on the stack to coincide with the position where the
- /// parser enters the new scope, and this object's constructor will
- /// create that new scope. Similarly, once the object is destroyed
- /// the parser will exit the scope.
- class ParseScope {
- Parser *Self;
- ParseScope(const ParseScope &) = delete;
- void operator=(const ParseScope &) = delete;
- public:
- // ParseScope - Construct a new object to manage a scope in the
- // parser Self where the new Scope is created with the flags
- // ScopeFlags, but only when we aren't about to enter a compound statement.
- ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
- bool BeforeCompoundStmt = false)
- : Self(Self) {
- if (EnteredScope && !BeforeCompoundStmt)
- Self->EnterScope(ScopeFlags);
- else {
- if (BeforeCompoundStmt)
- Self->incrementMSManglingNumber();
- this->Self = nullptr;
- }
- }
- // Exit - Exit the scope associated with this object now, rather
- // than waiting until the object is destroyed.
- void Exit() {
- if (Self) {
- Self->ExitScope();
- Self = nullptr;
- }
- }
- ~ParseScope() {
- Exit();
- }
- };
- /// Introduces zero or more scopes for parsing. The scopes will all be exited
- /// when the object is destroyed.
- class MultiParseScope {
- Parser &Self;
- unsigned NumScopes = 0;
- MultiParseScope(const MultiParseScope&) = delete;
- public:
- MultiParseScope(Parser &Self) : Self(Self) {}
- void Enter(unsigned ScopeFlags) {
- Self.EnterScope(ScopeFlags);
- ++NumScopes;
- }
- void Exit() {
- while (NumScopes) {
- Self.ExitScope();
- --NumScopes;
- }
- }
- ~MultiParseScope() {
- Exit();
- }
- };
- /// EnterScope - Start a new scope.
- void EnterScope(unsigned ScopeFlags);
- /// ExitScope - Pop a scope off the scope stack.
- void ExitScope();
- /// Re-enter the template scopes for a declaration that might be a template.
- unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D);
- private:
- /// RAII object used to modify the scope flags for the current scope.
- class ParseScopeFlags {
- Scope *CurScope;
- unsigned OldFlags;
- ParseScopeFlags(const ParseScopeFlags &) = delete;
- void operator=(const ParseScopeFlags &) = delete;
- public:
- ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true);
- ~ParseScopeFlags();
- };
- //===--------------------------------------------------------------------===//
- // Diagnostic Emission and Error recovery.
- public:
- DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
- DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
- DiagnosticBuilder Diag(unsigned DiagID) {
- return Diag(Tok, DiagID);
- }
- private:
- void SuggestParentheses(SourceLocation Loc, unsigned DK,
- SourceRange ParenRange);
- void CheckNestedObjCContexts(SourceLocation AtLoc);
- public:
- /// Control flags for SkipUntil functions.
- enum SkipUntilFlags {
- StopAtSemi = 1 << 0, ///< Stop skipping at semicolon
- /// Stop skipping at specified token, but don't skip the token itself
- StopBeforeMatch = 1 << 1,
- StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
- };
- friend constexpr SkipUntilFlags operator|(SkipUntilFlags L,
- SkipUntilFlags R) {
- return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) |
- static_cast<unsigned>(R));
- }
- /// SkipUntil - Read tokens until we get to the specified token, then consume
- /// it (unless StopBeforeMatch is specified). Because we cannot guarantee
- /// that the token will ever occur, this skips to the next token, or to some
- /// likely good stopping point. If Flags has StopAtSemi flag, skipping will
- /// stop at a ';' character. Balances (), [], and {} delimiter tokens while
- /// skipping.
- ///
- /// If SkipUntil finds the specified token, it returns true, otherwise it
- /// returns false.
- bool SkipUntil(tok::TokenKind T,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
- return SkipUntil(llvm::makeArrayRef(T), Flags);
- }
- bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
- tok::TokenKind TokArray[] = {T1, T2};
- return SkipUntil(TokArray, Flags);
- }
- bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
- tok::TokenKind TokArray[] = {T1, T2, T3};
- return SkipUntil(TokArray, Flags);
- }
- bool SkipUntil(ArrayRef<tok::TokenKind> Toks,
- SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0));
- /// SkipMalformedDecl - Read tokens until we get to some likely good stopping
- /// point for skipping past a simple-declaration.
- void SkipMalformedDecl();
- /// The location of the first statement inside an else that might
- /// have a missleading indentation. If there is no
- /// MisleadingIndentationChecker on an else active, this location is invalid.
- SourceLocation MisleadingIndentationElseLoc;
- private:
- //===--------------------------------------------------------------------===//
- // Lexing and parsing of C++ inline methods.
- struct ParsingClass;
- /// [class.mem]p1: "... the class is regarded as complete within
- /// - function bodies
- /// - default arguments
- /// - exception-specifications (TODO: C++0x)
- /// - and brace-or-equal-initializers for non-static data members
- /// (including such things in nested classes)."
- /// LateParsedDeclarations build the tree of those elements so they can
- /// be parsed after parsing the top-level class.
- class LateParsedDeclaration {
- public:
- virtual ~LateParsedDeclaration();
- virtual void ParseLexedMethodDeclarations();
- virtual void ParseLexedMemberInitializers();
- virtual void ParseLexedMethodDefs();
- virtual void ParseLexedAttributes();
- virtual void ParseLexedPragmas();
- };
- /// Inner node of the LateParsedDeclaration tree that parses
- /// all its members recursively.
- class LateParsedClass : public LateParsedDeclaration {
- public:
- LateParsedClass(Parser *P, ParsingClass *C);
- ~LateParsedClass() override;
- void ParseLexedMethodDeclarations() override;
- void ParseLexedMemberInitializers() override;
- void ParseLexedMethodDefs() override;
- void ParseLexedAttributes() override;
- void ParseLexedPragmas() override;
- private:
- Parser *Self;
- ParsingClass *Class;
- };
- /// Contains the lexed tokens of an attribute with arguments that
- /// may reference member variables and so need to be parsed at the
- /// end of the class declaration after parsing all other member
- /// member declarations.
- /// FIXME: Perhaps we should change the name of LateParsedDeclaration to
- /// LateParsedTokens.
- struct LateParsedAttribute : public LateParsedDeclaration {
- Parser *Self;
- CachedTokens Toks;
- IdentifierInfo &AttrName;
- IdentifierInfo *MacroII = nullptr;
- SourceLocation AttrNameLoc;
- SmallVector<Decl*, 2> Decls;
- explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name,
- SourceLocation Loc)
- : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
- void ParseLexedAttributes() override;
- void addDecl(Decl *D) { Decls.push_back(D); }
- };
- /// Contains the lexed tokens of a pragma with arguments that
- /// may reference member variables and so need to be parsed at the
- /// end of the class declaration after parsing all other member
- /// member declarations.
- class LateParsedPragma : public LateParsedDeclaration {
- Parser *Self = nullptr;
- AccessSpecifier AS = AS_none;
- CachedTokens Toks;
- public:
- explicit LateParsedPragma(Parser *P, AccessSpecifier AS)
- : Self(P), AS(AS) {}
- void takeToks(CachedTokens &Cached) { Toks.swap(Cached); }
- const CachedTokens &toks() const { return Toks; }
- AccessSpecifier getAccessSpecifier() const { return AS; }
- void ParseLexedPragmas() override;
- };
- // A list of late-parsed attributes. Used by ParseGNUAttributes.
- class LateParsedAttrList: public SmallVector<LateParsedAttribute *, 2> {
- public:
- LateParsedAttrList(bool PSoon = false) : ParseSoon(PSoon) { }
- bool parseSoon() { return ParseSoon; }
- private:
- bool ParseSoon; // Are we planning to parse these shortly after creation?
- };
- /// Contains the lexed tokens of a member function definition
- /// which needs to be parsed at the end of the class declaration
- /// after parsing all other member declarations.
- struct LexedMethod : public LateParsedDeclaration {
- Parser *Self;
- Decl *D;
- CachedTokens Toks;
- explicit LexedMethod(Parser *P, Decl *MD) : Self(P), D(MD) {}
- void ParseLexedMethodDefs() override;
- };
- /// LateParsedDefaultArgument - Keeps track of a parameter that may
- /// have a default argument that cannot be parsed yet because it
- /// occurs within a member function declaration inside the class
- /// (C++ [class.mem]p2).
- struct LateParsedDefaultArgument {
- explicit LateParsedDefaultArgument(Decl *P,
- std::unique_ptr<CachedTokens> Toks = nullptr)
- : Param(P), Toks(std::move(Toks)) { }
- /// Param - The parameter declaration for this parameter.
- Decl *Param;
- /// Toks - The sequence of tokens that comprises the default
- /// argument expression, not including the '=' or the terminating
- /// ')' or ','. This will be NULL for parameters that have no
- /// default argument.
- std::unique_ptr<CachedTokens> Toks;
- };
- /// LateParsedMethodDeclaration - A method declaration inside a class that
- /// contains at least one entity whose parsing needs to be delayed
- /// until the class itself is completely-defined, such as a default
- /// argument (C++ [class.mem]p2).
- struct LateParsedMethodDeclaration : public LateParsedDeclaration {
- explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
- : Self(P), Method(M), ExceptionSpecTokens(nullptr) {}
- void ParseLexedMethodDeclarations() override;
- Parser *Self;
- /// Method - The method declaration.
- Decl *Method;
- /// DefaultArgs - Contains the parameters of the function and
- /// their default arguments. At least one of the parameters will
- /// have a default argument, but all of the parameters of the
- /// method will be stored so that they can be reintroduced into
- /// scope at the appropriate times.
- SmallVector<LateParsedDefaultArgument, 8> DefaultArgs;
- /// The set of tokens that make up an exception-specification that
- /// has not yet been parsed.
- CachedTokens *ExceptionSpecTokens;
- };
- /// LateParsedMemberInitializer - An initializer for a non-static class data
- /// member whose parsing must to be delayed until the class is completely
- /// defined (C++11 [class.mem]p2).
- struct LateParsedMemberInitializer : public LateParsedDeclaration {
- LateParsedMemberInitializer(Parser *P, Decl *FD)
- : Self(P), Field(FD) { }
- void ParseLexedMemberInitializers() override;
- Parser *Self;
- /// Field - The field declaration.
- Decl *Field;
- /// CachedTokens - The sequence of tokens that comprises the initializer,
- /// including any leading '='.
- CachedTokens Toks;
- };
- /// LateParsedDeclarationsContainer - During parsing of a top (non-nested)
- /// C++ class, its method declarations that contain parts that won't be
- /// parsed until after the definition is completed (C++ [class.mem]p2),
- /// the method declarations and possibly attached inline definitions
- /// will be stored here with the tokens that will be parsed to create those
- /// entities.
- typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer;
- /// Representation of a class that has been parsed, including
- /// any member function declarations or definitions that need to be
- /// parsed after the corresponding top-level class is complete.
- struct ParsingClass {
- ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface)
- : TopLevelClass(TopLevelClass), IsInterface(IsInterface),
- TagOrTemplate(TagOrTemplate) {}
- /// Whether this is a "top-level" class, meaning that it is
- /// not nested within another class.
- bool TopLevelClass : 1;
- /// Whether this class is an __interface.
- bool IsInterface : 1;
- /// The class or class template whose definition we are parsing.
- Decl *TagOrTemplate;
- /// LateParsedDeclarations - Method declarations, inline definitions and
- /// nested classes that contain pieces whose parsing will be delayed until
- /// the top-level class is fully defined.
- LateParsedDeclarationsContainer LateParsedDeclarations;
- };
- /// The stack of classes that is currently being
- /// parsed. Nested and local classes will be pushed onto this stack
- /// when they are parsed, and removed afterward.
- std::stack<ParsingClass *> ClassStack;
- ParsingClass &getCurrentClass() {
- assert(!ClassStack.empty() && "No lexed method stacks!");
- return *ClassStack.top();
- }
- /// RAII object used to manage the parsing of a class definition.
- class ParsingClassDefinition {
- Parser &P;
- bool Popped;
- Sema::ParsingClassState State;
- public:
- ParsingClassDefinition(Parser &P, Decl *TagOrTemplate, bool TopLevelClass,
- bool IsInterface)
- : P(P), Popped(false),
- State(P.PushParsingClass(TagOrTemplate, TopLevelClass, IsInterface)) {
- }
- /// Pop this class of the stack.
- void Pop() {
- assert(!Popped && "Nested class has already been popped");
- Popped = true;
- P.PopParsingClass(State);
- }
- ~ParsingClassDefinition() {
- if (!Popped)
- P.PopParsingClass(State);
- }
- };
- /// Contains information about any template-specific
- /// information that has been parsed prior to parsing declaration
- /// specifiers.
- struct ParsedTemplateInfo {
- ParsedTemplateInfo() : Kind(NonTemplate), TemplateParams(nullptr) {}
- ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
- bool isSpecialization,
- bool lastParameterListWasEmpty = false)
- : Kind(isSpecialization? ExplicitSpecialization : Template),
- TemplateParams(TemplateParams),
- LastParameterListWasEmpty(lastParameterListWasEmpty) { }
- explicit ParsedTemplateInfo(SourceLocation ExternLoc,
- SourceLocation TemplateLoc)
- : Kind(ExplicitInstantiation), TemplateParams(nullptr),
- ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
- LastParameterListWasEmpty(false){ }
- /// The kind of template we are parsing.
- enum {
- /// We are not parsing a template at all.
- NonTemplate = 0,
- /// We are parsing a template declaration.
- Template,
- /// We are parsing an explicit specialization.
- ExplicitSpecialization,
- /// We are parsing an explicit instantiation.
- ExplicitInstantiation
- } Kind;
- /// The template parameter lists, for template declarations
- /// and explicit specializations.
- TemplateParameterLists *TemplateParams;
- /// The location of the 'extern' keyword, if any, for an explicit
- /// instantiation
- SourceLocation ExternLoc;
- /// The location of the 'template' keyword, for an explicit
- /// instantiation.
- SourceLocation TemplateLoc;
- /// Whether the last template parameter list was empty.
- bool LastParameterListWasEmpty;
- SourceRange getSourceRange() const LLVM_READONLY;
- };
- // In ParseCXXInlineMethods.cpp.
- struct ReenterTemplateScopeRAII;
- struct ReenterClassScopeRAII;
- void LexTemplateFunctionForLateParsing(CachedTokens &Toks);
- void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT);
- static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
- Sema::ParsingClassState
- PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
- void DeallocateParsedClasses(ParsingClass *Class);
- void PopParsingClass(Sema::ParsingClassState);
- enum CachedInitKind {
- CIK_DefaultArgument,
- CIK_DefaultInitializer
- };
- NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
- ParsedAttributes &AccessAttrs,
- ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo,
- const VirtSpecifiers &VS,
- SourceLocation PureSpecLoc);
- void ParseCXXNonStaticMemberInitializer(Decl *VarD);
- void ParseLexedAttributes(ParsingClass &Class);
- void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
- bool EnterScope, bool OnDefinition);
- void ParseLexedAttribute(LateParsedAttribute &LA,
- bool EnterScope, bool OnDefinition);
- void ParseLexedMethodDeclarations(ParsingClass &Class);
- void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM);
- void ParseLexedMethodDefs(ParsingClass &Class);
- void ParseLexedMethodDef(LexedMethod &LM);
- void ParseLexedMemberInitializers(ParsingClass &Class);
- void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
- void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
- void ParseLexedPragmas(ParsingClass &Class);
- void ParseLexedPragma(LateParsedPragma &LP);
- bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
- bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK);
- bool ConsumeAndStoreConditional(CachedTokens &Toks);
- bool ConsumeAndStoreUntil(tok::TokenKind T1,
- CachedTokens &Toks,
- bool StopAtSemi = true,
- bool ConsumeFinalToken = true) {
- return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
- }
- bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
- CachedTokens &Toks,
- bool StopAtSemi = true,
- bool ConsumeFinalToken = true);
- //===--------------------------------------------------------------------===//
- // C99 6.9: External Definitions.
- DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
- ParsingDeclSpec *DS = nullptr);
- bool isDeclarationAfterDeclarator();
- bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
- DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
- ParsedAttributesWithRange &attrs,
- ParsingDeclSpec *DS = nullptr,
- AccessSpecifier AS = AS_none);
- DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
- ParsingDeclSpec &DS,
- AccessSpecifier AS);
- void SkipFunctionBody();
- Decl *ParseFunctionDefinition(ParsingDeclarator &D,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- LateParsedAttrList *LateParsedAttrs = nullptr);
- void ParseKNRParamDeclarations(Declarator &D);
- // EndLoc is filled with the location of the last token of the simple-asm.
- ExprResult ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc);
- ExprResult ParseAsmStringLiteral(bool ForAsmLabel);
- // Objective-C External Declarations
- void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
- DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs);
- DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
- Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
- ParsedAttributes &prefixAttrs);
- class ObjCTypeParamListScope;
- ObjCTypeParamList *parseObjCTypeParamList();
- ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs(
- ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc,
- SmallVectorImpl<IdentifierLocPair> &protocolIdents,
- SourceLocation &rAngleLoc, bool mayBeProtocolList = true);
- void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
- BalancedDelimiterTracker &T,
- SmallVectorImpl<Decl *> &AllIvarDecls,
- bool RBraceMissing);
- void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
- tok::ObjCKeywordKind visibility,
- SourceLocation atLoc);
- bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P,
- SmallVectorImpl<SourceLocation> &PLocs,
- bool WarnOnDeclarations,
- bool ForObjCContainer,
- SourceLocation &LAngleLoc,
- SourceLocation &EndProtoLoc,
- bool consumeLastToken);
- /// Parse the first angle-bracket-delimited clause for an
- /// Objective-C object or object pointer type, which may be either
- /// type arguments or protocol qualifiers.
- void parseObjCTypeArgsOrProtocolQualifiers(
- ParsedType baseType,
- SourceLocation &typeArgsLAngleLoc,
- SmallVectorImpl<ParsedType> &typeArgs,
- SourceLocation &typeArgsRAngleLoc,
- SourceLocation &protocolLAngleLoc,
- SmallVectorImpl<Decl *> &protocols,
- SmallVectorImpl<SourceLocation> &protocolLocs,
- SourceLocation &protocolRAngleLoc,
- bool consumeLastToken,
- bool warnOnIncompleteProtocols);
- /// Parse either Objective-C type arguments or protocol qualifiers; if the
- /// former, also parse protocol qualifiers afterward.
- void parseObjCTypeArgsAndProtocolQualifiers(
- ParsedType baseType,
- SourceLocation &typeArgsLAngleLoc,
- SmallVectorImpl<ParsedType> &typeArgs,
- SourceLocation &typeArgsRAngleLoc,
- SourceLocation &protocolLAngleLoc,
- SmallVectorImpl<Decl *> &protocols,
- SmallVectorImpl<SourceLocation> &protocolLocs,
- SourceLocation &protocolRAngleLoc,
- bool consumeLastToken);
- /// Parse a protocol qualifier type such as '<NSCopying>', which is
- /// an anachronistic way of writing 'id<NSCopying>'.
- TypeResult parseObjCProtocolQualifierType(SourceLocation &rAngleLoc);
- /// Parse Objective-C type arguments and protocol qualifiers, extending the
- /// current type with the parsed result.
- TypeResult parseObjCTypeArgsAndProtocolQualifiers(SourceLocation loc,
- ParsedType type,
- bool consumeLastToken,
- SourceLocation &endLoc);
- void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
- Decl *CDecl);
- DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
- ParsedAttributes &prefixAttrs);
- struct ObjCImplParsingDataRAII {
- Parser &P;
- Decl *Dcl;
- bool HasCFunction;
- typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
- LateParsedObjCMethodContainer LateParsedObjCMethods;
- ObjCImplParsingDataRAII(Parser &parser, Decl *D)
- : P(parser), Dcl(D), HasCFunction(false) {
- P.CurParsedObjCImpl = this;
- Finished = false;
- }
- ~ObjCImplParsingDataRAII();
- void finish(SourceRange AtEnd);
- bool isFinished() const { return Finished; }
- private:
- bool Finished;
- };
- ObjCImplParsingDataRAII *CurParsedObjCImpl;
- void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
- DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
- ParsedAttributes &Attrs);
- DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
- Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
- Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
- Decl *ParseObjCPropertyDynamic(SourceLocation atLoc);
- IdentifierInfo *ParseObjCSelectorPiece(SourceLocation &MethodLocation);
- // Definitions for Objective-c context sensitive keywords recognition.
- enum ObjCTypeQual {
- objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
- objc_nonnull, objc_nullable, objc_null_unspecified,
- objc_NumQuals
- };
- IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
- bool isTokIdentifier_in() const;
- ParsedType ParseObjCTypeName(ObjCDeclSpec &DS, DeclaratorContext Ctx,
- ParsedAttributes *ParamAttrs);
- Decl *ParseObjCMethodPrototype(
- tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
- bool MethodDefinition = true);
- Decl *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
- tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword,
- bool MethodDefinition=true);
- void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
- Decl *ParseObjCMethodDefinition();
- public:
- //===--------------------------------------------------------------------===//
- // C99 6.5: Expressions.
- /// TypeCastState - State whether an expression is or may be a type cast.
- enum TypeCastState {
- NotTypeCast = 0,
- MaybeTypeCast,
- IsTypeCast
- };
- ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
- ExprResult ParseConstantExpressionInExprEvalContext(
- TypeCastState isTypeCast = NotTypeCast);
- ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast);
- ExprResult ParseCaseExpression(SourceLocation CaseLoc);
- ExprResult ParseConstraintExpression();
- ExprResult
- ParseConstraintLogicalAndExpression(bool IsTrailingRequiresClause);
- ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause);
- // Expr that doesn't include commas.
- ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast);
- ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
- unsigned &NumLineToksConsumed,
- bool IsUnevaluated);
- ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
- private:
- ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
- ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
- ExprResult ParseRHSOfBinaryExpression(ExprResult LHS,
- prec::Level MinPrec);
- /// Control what ParseCastExpression will parse.
- enum CastParseKind {
- AnyCastExpr = 0,
- UnaryExprOnly,
- PrimaryExprOnly
- };
- ExprResult ParseCastExpression(CastParseKind ParseKind,
- bool isAddressOfOperand,
- bool &NotCastExpr,
- TypeCastState isTypeCast,
- bool isVectorLiteral = false,
- bool *NotPrimaryExpression = nullptr);
- ExprResult ParseCastExpression(CastParseKind ParseKind,
- bool isAddressOfOperand = false,
- TypeCastState isTypeCast = NotTypeCast,
- bool isVectorLiteral = false,
- bool *NotPrimaryExpression = nullptr);
- /// Returns true if the next token cannot start an expression.
- bool isNotExpressionStart();
- /// Returns true if the next token would start a postfix-expression
- /// suffix.
- bool isPostfixExpressionSuffixStart() {
- tok::TokenKind K = Tok.getKind();
- return (K == tok::l_square || K == tok::l_paren ||
- K == tok::period || K == tok::arrow ||
- K == tok::plusplus || K == tok::minusminus);
- }
- bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
- void checkPotentialAngleBracket(ExprResult &PotentialTemplateName);
- bool checkPotentialAngleBracketDelimiter(const AngleBracketTracker::Loc &,
- const Token &OpToken);
- bool checkPotentialAngleBracketDelimiter(const Token &OpToken) {
- if (auto *Info = AngleBrackets.getCurrent(*this))
- return checkPotentialAngleBracketDelimiter(*Info, OpToken);
- return false;
- }
- ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
- ExprResult ParseUnaryExprOrTypeTraitExpression();
- ExprResult ParseBuiltinPrimaryExpression();
- ExprResult ParseSYCLUniqueStableNameExpression();
- ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
- bool &isCastExpr,
- ParsedType &CastTy,
- SourceRange &CastRange);
- typedef SmallVector<SourceLocation, 20> CommaLocsTy;
- /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
- bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs,
- llvm::function_ref<void()> ExpressionStarts =
- llvm::function_ref<void()>());
- /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
- /// used for misc language extensions.
- bool ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs);
- /// ParenParseOption - Control what ParseParenExpression will parse.
- enum ParenParseOption {
- SimpleExpr, // Only parse '(' expression ')'
- FoldExpr, // Also allow fold-expression <anything>
- CompoundStmt, // Also allow '(' compound-statement ')'
- CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
- CastExpr // Also allow '(' type-name ')' <anything>
- };
- ExprResult ParseParenExpression(ParenParseOption &ExprType,
- bool stopIfCastExpr,
- bool isTypeCast,
- ParsedType &CastTy,
- SourceLocation &RParenLoc);
- ExprResult ParseCXXAmbiguousParenExpression(
- ParenParseOption &ExprType, ParsedType &CastTy,
- BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
- ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc);
- ExprResult ParseGenericSelectionExpression();
- ExprResult ParseObjCBoolLiteral();
- ExprResult ParseFoldExpression(ExprResult LHS, BalancedDelimiterTracker &T);
- //===--------------------------------------------------------------------===//
- // C++ Expressions
- ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOperand,
- Token &Replacement);
- ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false);
- bool areTokensAdjacent(const Token &A, const Token &B);
- void CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectTypePtr,
- bool EnteringContext, IdentifierInfo &II,
- CXXScopeSpec &SS);
- bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
- ParsedType ObjectType,
- bool ObjectHasErrors,
- bool EnteringContext,
- bool *MayBePseudoDestructor = nullptr,
- bool IsTypename = false,
- IdentifierInfo **LastII = nullptr,
- bool OnlyNamespace = false,
- bool InUsingDeclaration = false);
- //===--------------------------------------------------------------------===//
- // C++11 5.1.2: Lambda expressions
- /// Result of tentatively parsing a lambda-introducer.
- enum class LambdaIntroducerTentativeParse {
- /// This appears to be a lambda-introducer, which has been fully parsed.
- Success,
- /// This is a lambda-introducer, but has not been fully parsed, and this
- /// function needs to be called again to parse it.
- Incomplete,
- /// This is definitely an Objective-C message send expression, rather than
- /// a lambda-introducer, attribute-specifier, or array designator.
- MessageSend,
- /// This is not a lambda-introducer.
- Invalid,
- };
- // [...] () -> type {...}
- ExprResult ParseLambdaExpression();
- ExprResult TryParseLambdaExpression();
- bool
- ParseLambdaIntroducer(LambdaIntroducer &Intro,
- LambdaIntroducerTentativeParse *Tentative = nullptr);
- ExprResult ParseLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro);
- //===--------------------------------------------------------------------===//
- // C++ 5.2p1: C++ Casts
- ExprResult ParseCXXCasts();
- /// Parse a __builtin_bit_cast(T, E), used to implement C++2a std::bit_cast.
- ExprResult ParseBuiltinBitCast();
- //===--------------------------------------------------------------------===//
- // C++ 5.2p1: C++ Type Identification
- ExprResult ParseCXXTypeid();
- //===--------------------------------------------------------------------===//
- // C++ : Microsoft __uuidof Expression
- ExprResult ParseCXXUuidof();
- //===--------------------------------------------------------------------===//
- // C++ 5.2.4: C++ Pseudo-Destructor Expressions
- ExprResult ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,
- tok::TokenKind OpKind,
- CXXScopeSpec &SS,
- ParsedType ObjectType);
- //===--------------------------------------------------------------------===//
- // C++ 9.3.2: C++ 'this' pointer
- ExprResult ParseCXXThis();
- //===--------------------------------------------------------------------===//
- // C++ 15: C++ Throw Expression
- ExprResult ParseThrowExpression();
- ExceptionSpecificationType tryParseExceptionSpecification(
- bool Delayed,
- SourceRange &SpecificationRange,
- SmallVectorImpl<ParsedType> &DynamicExceptions,
- SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
- ExprResult &NoexceptExpr,
- CachedTokens *&ExceptionSpecTokens);
- // EndLoc is filled with the location of the last token of the specification.
- ExceptionSpecificationType ParseDynamicExceptionSpecification(
- SourceRange &SpecificationRange,
- SmallVectorImpl<ParsedType> &Exceptions,
- SmallVectorImpl<SourceRange> &Ranges);
- //===--------------------------------------------------------------------===//
- // C++0x 8: Function declaration trailing-return-type
- TypeResult ParseTrailingReturnType(SourceRange &Range,
- bool MayBeFollowedByDirectInit);
- //===--------------------------------------------------------------------===//
- // C++ 2.13.5: C++ Boolean Literals
- ExprResult ParseCXXBoolLiteral();
- //===--------------------------------------------------------------------===//
- // C++ 5.2.3: Explicit type conversion (functional notation)
- ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
- /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
- /// This should only be called when the current token is known to be part of
- /// simple-type-specifier.
- void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
- bool ParseCXXTypeSpecifierSeq(DeclSpec &DS);
- //===--------------------------------------------------------------------===//
- // C++ 5.3.4 and 5.3.5: C++ new and delete
- bool ParseExpressionListOrTypeId(SmallVectorImpl<Expr*> &Exprs,
- Declarator &D);
- void ParseDirectNewDeclarator(Declarator &D);
- ExprResult ParseCXXNewExpression(bool UseGlobal, SourceLocation Start);
- ExprResult ParseCXXDeleteExpression(bool UseGlobal,
- SourceLocation Start);
- //===--------------------------------------------------------------------===//
- // C++ if/switch/while/for condition expression.
- struct ForRangeInfo;
- Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt,
- SourceLocation Loc,
- Sema::ConditionKind CK,
- bool MissingOK,
- ForRangeInfo *FRI = nullptr,
- bool EnterForConditionScope = false);
- DeclGroupPtrTy
- ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
- ParsedAttributesWithRange &Attrs);
- //===--------------------------------------------------------------------===//
- // C++ Coroutines
- ExprResult ParseCoyieldExpression();
- //===--------------------------------------------------------------------===//
- // C++ Concepts
- ExprResult ParseRequiresExpression();
- void ParseTrailingRequiresClause(Declarator &D);
- //===--------------------------------------------------------------------===//
- // C99 6.7.8: Initialization.
- /// ParseInitializer
- /// initializer: [C99 6.7.8]
- /// assignment-expression
- /// '{' ...
- ExprResult ParseInitializer() {
- if (Tok.isNot(tok::l_brace))
- return ParseAssignmentExpression();
- return ParseBraceInitializer();
- }
- bool MayBeDesignationStart();
- ExprResult ParseBraceInitializer();
- struct DesignatorCompletionInfo {
- SmallVectorImpl<Expr *> &InitExprs;
- QualType PreferredBaseType;
- };
- ExprResult ParseInitializerWithPotentialDesignator(DesignatorCompletionInfo);
- //===--------------------------------------------------------------------===//
- // clang Expressions
- ExprResult ParseBlockLiteralExpression(); // ^{...}
- //===--------------------------------------------------------------------===//
- // Objective-C Expressions
- ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
- ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
- ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
- ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
- ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
- ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
- ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
- bool isSimpleObjCMessageExpression();
- ExprResult ParseObjCMessageExpression();
- ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
- SourceLocation SuperLoc,
- ParsedType ReceiverType,
- Expr *ReceiverExpr);
- ExprResult ParseAssignmentExprWithObjCMessageExprStart(
- SourceLocation LBracloc, SourceLocation SuperLoc,
- ParsedType ReceiverType, Expr *ReceiverExpr);
- bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
- //===--------------------------------------------------------------------===//
- // C99 6.8: Statements and Blocks.
- /// A SmallVector of statements, with stack size 32 (as that is the only one
- /// used.)
- typedef SmallVector<Stmt*, 32> StmtVector;
- /// A SmallVector of expressions, with stack size 12 (the maximum used.)
- typedef SmallVector<Expr*, 12> ExprVector;
- /// A SmallVector of types.
- typedef SmallVector<ParsedType, 12> TypeVector;
- StmtResult
- ParseStatement(SourceLocation *TrailingElseLoc = nullptr,
- ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt);
- StmtResult ParseStatementOrDeclaration(
- StmtVector &Stmts, ParsedStmtContext StmtCtx,
- SourceLocation *TrailingElseLoc = nullptr);
- StmtResult ParseStatementOrDeclarationAfterAttributes(
- StmtVector &Stmts,
- ParsedStmtContext StmtCtx,
- SourceLocation *TrailingElseLoc,
- ParsedAttributesWithRange &Attrs);
- StmtResult ParseExprStatement(ParsedStmtContext StmtCtx);
- StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs,
- ParsedStmtContext StmtCtx);
- StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx,
- bool MissingCase = false,
- ExprResult Expr = ExprResult());
- StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx);
- StmtResult ParseCompoundStatement(bool isStmtExpr = false);
- StmtResult ParseCompoundStatement(bool isStmtExpr,
- unsigned ScopeFlags);
- void ParseCompoundStatementLeadingPragmas();
- bool ConsumeNullStmt(StmtVector &Stmts);
- StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
- bool ParseParenExprOrCondition(StmtResult *InitStmt,
- Sema::ConditionResult &CondResult,
- SourceLocation Loc, Sema::ConditionKind CK,
- bool MissingOK, SourceLocation *LParenLoc,
- SourceLocation *RParenLoc);
- StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseDoStatement();
- StmtResult ParseForStatement(SourceLocation *TrailingElseLoc);
- StmtResult ParseGotoStatement();
- StmtResult ParseContinueStatement();
- StmtResult ParseBreakStatement();
- StmtResult ParseReturnStatement();
- StmtResult ParseAsmStatement(bool &msAsm);
- StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
- StmtResult ParsePragmaLoopHint(StmtVector &Stmts,
- ParsedStmtContext StmtCtx,
- SourceLocation *TrailingElseLoc,
- ParsedAttributesWithRange &Attrs);
- /// Describes the behavior that should be taken for an __if_exists
- /// block.
- enum IfExistsBehavior {
- /// Parse the block; this code is always used.
- IEB_Parse,
- /// Skip the block entirely; this code is never used.
- IEB_Skip,
- /// Parse the block as a dependent block, which may be used in
- /// some template instantiations but not others.
- IEB_Dependent
- };
- /// Describes the condition of a Microsoft __if_exists or
- /// __if_not_exists block.
- struct IfExistsCondition {
- /// The location of the initial keyword.
- SourceLocation KeywordLoc;
- /// Whether this is an __if_exists block (rather than an
- /// __if_not_exists block).
- bool IsIfExists;
- /// Nested-name-specifier preceding the name.
- CXXScopeSpec SS;
- /// The name we're looking for.
- UnqualifiedId Name;
- /// The behavior of this __if_exists or __if_not_exists block
- /// should.
- IfExistsBehavior Behavior;
- };
- bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result);
- void ParseMicrosoftIfExistsStatement(StmtVector &Stmts);
- void ParseMicrosoftIfExistsExternalDeclaration();
- void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
- ParsedAttributes &AccessAttrs,
- AccessSpecifier &CurAS);
- bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
- bool &InitExprsOk);
- bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
- SmallVectorImpl<Expr *> &Constraints,
- SmallVectorImpl<Expr *> &Exprs);
- //===--------------------------------------------------------------------===//
- // C++ 6: Statements and Blocks
- StmtResult ParseCXXTryBlock();
- StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry = false);
- StmtResult ParseCXXCatchBlock(bool FnCatch = false);
- //===--------------------------------------------------------------------===//
- // MS: SEH Statements and Blocks
- StmtResult ParseSEHTryBlock();
- StmtResult ParseSEHExceptBlock(SourceLocation Loc);
- StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
- StmtResult ParseSEHLeaveStatement();
- //===--------------------------------------------------------------------===//
- // Objective-C Statements
- StmtResult ParseObjCAtStatement(SourceLocation atLoc,
- ParsedStmtContext StmtCtx);
- StmtResult ParseObjCTryStmt(SourceLocation atLoc);
- StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
- StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
- StmtResult ParseObjCAutoreleasePoolStmt(SourceLocation atLoc);
- //===--------------------------------------------------------------------===//
- // C99 6.7: Declarations.
- /// A context for parsing declaration specifiers. TODO: flesh this
- /// out, there are other significant restrictions on specifiers than
- /// would be best implemented in the parser.
- enum class DeclSpecContext {
- DSC_normal, // normal context
- DSC_class, // class context, enables 'friend'
- DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
- DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
- DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
- DSC_top_level, // top-level/namespace declaration context
- DSC_template_param, // template parameter context
- DSC_template_type_arg, // template type argument context
- DSC_objc_method_result, // ObjC method result context, enables 'instancetype'
- DSC_condition // condition declaration context
- };
- /// Is this a context in which we are parsing just a type-specifier (or
- /// trailing-type-specifier)?
- static bool isTypeSpecifier(DeclSpecContext DSC) {
- switch (DSC) {
- case DeclSpecContext::DSC_normal:
- case DeclSpecContext::DSC_template_param:
- case DeclSpecContext::DSC_class:
- case DeclSpecContext::DSC_top_level:
- case DeclSpecContext::DSC_objc_method_result:
- case DeclSpecContext::DSC_condition:
- return false;
- case DeclSpecContext::DSC_template_type_arg:
- case DeclSpecContext::DSC_type_specifier:
- case DeclSpecContext::DSC_trailing:
- case DeclSpecContext::DSC_alias_declaration:
- return true;
- }
- llvm_unreachable("Missing DeclSpecContext case");
- }
- /// Whether a defining-type-specifier is permitted in a given context.
- enum class AllowDefiningTypeSpec {
- /// The grammar doesn't allow a defining-type-specifier here, and we must
- /// not parse one (eg, because a '{' could mean something else).
- No,
- /// The grammar doesn't allow a defining-type-specifier here, but we permit
- /// one for error recovery purposes. Sema will reject.
- NoButErrorRecovery,
- /// The grammar allows a defining-type-specifier here, even though it's
- /// always invalid. Sema will reject.
- YesButInvalid,
- /// The grammar allows a defining-type-specifier here, and one can be valid.
- Yes
- };
- /// Is this a context in which we are parsing defining-type-specifiers (and
- /// so permit class and enum definitions in addition to non-defining class and
- /// enum elaborated-type-specifiers)?
- static AllowDefiningTypeSpec
- isDefiningTypeSpecifierContext(DeclSpecContext DSC) {
- switch (DSC) {
- case DeclSpecContext::DSC_normal:
- case DeclSpecContext::DSC_class:
- case DeclSpecContext::DSC_top_level:
- case DeclSpecContext::DSC_alias_declaration:
- case DeclSpecContext::DSC_objc_method_result:
- return AllowDefiningTypeSpec::Yes;
- case DeclSpecContext::DSC_condition:
- case DeclSpecContext::DSC_template_param:
- return AllowDefiningTypeSpec::YesButInvalid;
- case DeclSpecContext::DSC_template_type_arg:
- case DeclSpecContext::DSC_type_specifier:
- return AllowDefiningTypeSpec::NoButErrorRecovery;
- case DeclSpecContext::DSC_trailing:
- return AllowDefiningTypeSpec::No;
- }
- llvm_unreachable("Missing DeclSpecContext case");
- }
- /// Is this a context in which an opaque-enum-declaration can appear?
- static bool isOpaqueEnumDeclarationContext(DeclSpecContext DSC) {
- switch (DSC) {
- case DeclSpecContext::DSC_normal:
- case DeclSpecContext::DSC_class:
- case DeclSpecContext::DSC_top_level:
- return true;
- case DeclSpecContext::DSC_alias_declaration:
- case DeclSpecContext::DSC_objc_method_result:
- case DeclSpecContext::DSC_condition:
- case DeclSpecContext::DSC_template_param:
- case DeclSpecContext::DSC_template_type_arg:
- case DeclSpecContext::DSC_type_specifier:
- case DeclSpecContext::DSC_trailing:
- return false;
- }
- llvm_unreachable("Missing DeclSpecContext case");
- }
- /// Is this a context in which we can perform class template argument
- /// deduction?
- static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
- switch (DSC) {
- case DeclSpecContext::DSC_normal:
- case DeclSpecContext::DSC_template_param:
- case DeclSpecContext::DSC_class:
- case DeclSpecContext::DSC_top_level:
- case DeclSpecContext::DSC_condition:
- case DeclSpecContext::DSC_type_specifier:
- return true;
- case DeclSpecContext::DSC_objc_method_result:
- case DeclSpecContext::DSC_template_type_arg:
- case DeclSpecContext::DSC_trailing:
- case DeclSpecContext::DSC_alias_declaration:
- return false;
- }
- llvm_unreachable("Missing DeclSpecContext case");
- }
- /// Information on a C++0x for-range-initializer found while parsing a
- /// declaration which turns out to be a for-range-declaration.
- struct ForRangeInit {
- SourceLocation ColonLoc;
- ExprResult RangeExpr;
- bool ParsedForRangeDecl() { return !ColonLoc.isInvalid(); }
- };
- struct ForRangeInfo : ForRangeInit {
- StmtResult LoopVar;
- };
- DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
- SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs,
- SourceLocation *DeclSpecStart = nullptr);
- DeclGroupPtrTy
- ParseSimpleDeclaration(DeclaratorContext Context, SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs, bool RequireSemi,
- ForRangeInit *FRI = nullptr,
- SourceLocation *DeclSpecStart = nullptr);
- bool MightBeDeclarator(DeclaratorContext Context);
- DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, DeclaratorContext Context,
- SourceLocation *DeclEnd = nullptr,
- ForRangeInit *FRI = nullptr);
- Decl *ParseDeclarationAfterDeclarator(Declarator &D,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
- bool ParseAsmAttributesAfterDeclarator(Declarator &D);
- Decl *ParseDeclarationAfterDeclaratorAndAttributes(
- Declarator &D,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- ForRangeInit *FRI = nullptr);
- Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
- Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
- /// When in code-completion, skip parsing of the function/method body
- /// unless the body contains the code-completion point.
- ///
- /// \returns true if the function body was skipped.
- bool trySkippingFunctionBody();
- bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
- const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS, DeclSpecContext DSC,
- ParsedAttributesWithRange &Attrs);
- DeclSpecContext
- getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
- void ParseDeclarationSpecifiers(
- DeclSpec &DS,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- AccessSpecifier AS = AS_none,
- DeclSpecContext DSC = DeclSpecContext::DSC_normal,
- LateParsedAttrList *LateAttrs = nullptr);
- bool DiagnoseMissingSemiAfterTagDefinition(
- DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext,
- LateParsedAttrList *LateAttrs = nullptr);
- void ParseSpecifierQualifierList(
- DeclSpec &DS, AccessSpecifier AS = AS_none,
- DeclSpecContext DSC = DeclSpecContext::DSC_normal);
- void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
- DeclaratorContext Context);
- void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
- const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS, DeclSpecContext DSC);
- void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
- void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
- RecordDecl *TagDecl);
- void ParseStructDeclaration(
- ParsingDeclSpec &DS,
- llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback);
- bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
- bool isTypeSpecifierQualifier();
- /// isKnownToBeTypeSpecifier - Return true if we know that the specified token
- /// is definitely a type-specifier. Return false if it isn't part of a type
- /// specifier or if we're not sure.
- bool isKnownToBeTypeSpecifier(const Token &Tok) const;
- /// Return true if we know that we are definitely looking at a
- /// decl-specifier, and isn't part of an expression such as a function-style
- /// cast. Return false if it's no a decl-specifier, or we're not sure.
- bool isKnownToBeDeclarationSpecifier() {
- if (getLangOpts().CPlusPlus)
- return isCXXDeclarationSpecifier() == TPResult::True;
- return isDeclarationSpecifier(true);
- }
- /// isDeclarationStatement - Disambiguates between a declaration or an
- /// expression statement, when parsing function bodies.
- /// Returns true for declaration, false for expression.
- bool isDeclarationStatement() {
- if (getLangOpts().CPlusPlus)
- return isCXXDeclarationStatement();
- return isDeclarationSpecifier(true);
- }
- /// isForInitDeclaration - Disambiguates between a declaration or an
- /// expression in the context of the C 'clause-1' or the C++
- // 'for-init-statement' part of a 'for' statement.
- /// Returns true for declaration, false for expression.
- bool isForInitDeclaration() {
- if (getLangOpts().OpenMP)
- Actions.startOpenMPLoop();
- if (getLangOpts().CPlusPlus)
- return Tok.is(tok::kw_using) ||
- isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
- return isDeclarationSpecifier(true);
- }
- /// Determine whether this is a C++1z for-range-identifier.
- bool isForRangeIdentifier();
- /// Determine whether we are currently at the start of an Objective-C
- /// class message that appears to be missing the open bracket '['.
- bool isStartOfObjCClassMessageMissingOpenBracket();
- /// Starting with a scope specifier, identifier, or
- /// template-id that refers to the current class, determine whether
- /// this is a constructor declarator.
- bool isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false);
- /// Specifies the context in which type-id/expression
- /// disambiguation will occur.
- enum TentativeCXXTypeIdContext {
- TypeIdInParens,
- TypeIdUnambiguous,
- TypeIdAsTemplateArgument
- };
- /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
- /// whether the parens contain an expression or a type-id.
- /// Returns true for a type-id and false for an expression.
- bool isTypeIdInParens(bool &isAmbiguous) {
- if (getLangOpts().CPlusPlus)
- return isCXXTypeId(TypeIdInParens, isAmbiguous);
- isAmbiguous = false;
- return isTypeSpecifierQualifier();
- }
- bool isTypeIdInParens() {
- bool isAmbiguous;
- return isTypeIdInParens(isAmbiguous);
- }
- /// Checks if the current tokens form type-id or expression.
- /// It is similar to isTypeIdInParens but does not suppose that type-id
- /// is in parenthesis.
- bool isTypeIdUnambiguously() {
- bool IsAmbiguous;
- if (getLangOpts().CPlusPlus)
- return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous);
- return isTypeSpecifierQualifier();
- }
- /// isCXXDeclarationStatement - C++-specialized function that disambiguates
- /// between a declaration or an expression statement, when parsing function
- /// bodies. Returns true for declaration, false for expression.
- bool isCXXDeclarationStatement();
- /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
- /// between a simple-declaration or an expression-statement.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- /// Returns false if the statement is disambiguated as expression.
- bool isCXXSimpleDeclaration(bool AllowForRangeDecl);
- /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
- /// a constructor-style initializer, when parsing declaration statements.
- /// Returns true for function declarator and false for constructor-style
- /// initializer. Sets 'IsAmbiguous' to true to indicate that this declaration
- /// might be a constructor-style initializer.
- /// If during the disambiguation process a parsing error is encountered,
- /// the function returns true to let the declaration parsing code handle it.
- bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr);
- struct ConditionDeclarationOrInitStatementState;
- enum class ConditionOrInitStatement {
- Expression, ///< Disambiguated as an expression (either kind).
- ConditionDecl, ///< Disambiguated as the declaration form of condition.
- InitStmtDecl, ///< Disambiguated as a simple-declaration init-statement.
- ForRangeDecl, ///< Disambiguated as a for-range declaration.
- Error ///< Can't be any of the above!
- };
- /// Disambiguates between the different kinds of things that can happen
- /// after 'if (' or 'switch ('. This could be one of two different kinds of
- /// declaration (depending on whether there is a ';' later) or an expression.
- ConditionOrInitStatement
- isCXXConditionDeclarationOrInitStatement(bool CanBeInitStmt,
- bool CanBeForRangeDecl);
- bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous);
- bool isCXXTypeId(TentativeCXXTypeIdContext Context) {
- bool isAmbiguous;
- return isCXXTypeId(Context, isAmbiguous);
- }
- /// TPResult - Used as the result value for functions whose purpose is to
- /// disambiguate C++ constructs by "tentatively parsing" them.
- enum class TPResult {
- True, False, Ambiguous, Error
- };
- /// Determine whether we could have an enum-base.
- ///
- /// \p AllowSemi If \c true, then allow a ';' after the enum-base; otherwise
- /// only consider this to be an enum-base if the next token is a '{'.
- ///
- /// \return \c false if this cannot possibly be an enum base; \c true
- /// otherwise.
- bool isEnumBase(bool AllowSemi);
- /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
- /// declaration specifier, TPResult::False if it is not,
- /// TPResult::Ambiguous if it could be either a decl-specifier or a
- /// function-style cast, and TPResult::Error if a parsing error was
- /// encountered. If it could be a braced C++11 function-style cast, returns
- /// BracedCastResult.
- /// Doesn't consume tokens.
- TPResult
- isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False,
- bool *InvalidAsDeclSpec = nullptr);
- /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
- /// \c TPResult::Ambiguous, determine whether the decl-specifier would be
- /// a type-specifier other than a cv-qualifier.
- bool isCXXDeclarationSpecifierAType();
- /// Determine whether the current token sequence might be
- /// '<' template-argument-list '>'
- /// rather than a less-than expression.
- TPResult isTemplateArgumentList(unsigned TokensToSkip);
- /// Determine whether an '(' after an 'explicit' keyword is part of a C++20
- /// 'explicit(bool)' declaration, in earlier language modes where that is an
- /// extension.
- TPResult isExplicitBool();
- /// Determine whether an identifier has been tentatively declared as a
- /// non-type. Such tentative declarations should not be found to name a type
- /// during a tentative parse, but also should not be annotated as a non-type.
- bool isTentativelyDeclared(IdentifierInfo *II);
- // "Tentative parsing" functions, used for disambiguation. If a parsing error
- // is encountered they will return TPResult::Error.
- // Returning TPResult::True/False indicates that the ambiguity was
- // resolved and tentative parsing may stop. TPResult::Ambiguous indicates
- // that more tentative parsing is necessary for disambiguation.
- // They all consume tokens, so backtracking should be used after calling them.
- TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl);
- TPResult TryParseTypeofSpecifier();
- TPResult TryParseProtocolQualifiers();
- TPResult TryParsePtrOperatorSeq();
- TPResult TryParseOperatorId();
- TPResult TryParseInitDeclaratorList();
- TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
- bool mayHaveDirectInit = false);
- TPResult
- TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr,
- bool VersusTemplateArg = false);
- TPResult TryParseFunctionDeclarator();
- TPResult TryParseBracketDeclarator();
- TPResult TryConsumeDeclarationSpecifier();
- /// Try to skip a possibly empty sequence of 'attribute-specifier's without
- /// full validation of the syntactic structure of attributes.
- bool TrySkipAttributes();
- /// Diagnoses use of _ExtInt as being deprecated, and diagnoses use of
- /// _BitInt as an extension when appropriate.
- void DiagnoseBitIntUse(const Token &Tok);
- public:
- TypeResult
- ParseTypeName(SourceRange *Range = nullptr,
- DeclaratorContext Context = DeclaratorContext::TypeName,
- AccessSpecifier AS = AS_none, Decl **OwnedType = nullptr,
- ParsedAttributes *Attrs = nullptr);
- private:
- void ParseBlockId(SourceLocation CaretLoc);
- /// Are [[]] attributes enabled?
- bool standardAttributesAllowed() const {
- const LangOptions &LO = getLangOpts();
- return LO.DoubleSquareBracketAttributes;
- }
- // Check for the start of an attribute-specifier-seq in a context where an
- // attribute is not allowed.
- bool CheckProhibitedCXX11Attribute() {
- assert(Tok.is(tok::l_square));
- if (!standardAttributesAllowed() || NextToken().isNot(tok::l_square))
- return false;
- return DiagnoseProhibitedCXX11Attribute();
- }
- bool DiagnoseProhibitedCXX11Attribute();
- void CheckMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
- SourceLocation CorrectLocation) {
- if (!standardAttributesAllowed())
- return;
- if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
- Tok.isNot(tok::kw_alignas))
- return;
- DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
- }
- void DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
- SourceLocation CorrectLocation);
- void stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
- DeclSpec &DS, Sema::TagUseKind TUK);
- // FixItLoc = possible correct location for the attributes
- void ProhibitAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation FixItLoc = SourceLocation()) {
- if (Attrs.Range.isInvalid())
- return;
- DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
- Attrs.clear();
- }
- void ProhibitAttributes(ParsedAttributesViewWithRange &Attrs,
- SourceLocation FixItLoc = SourceLocation()) {
- if (Attrs.Range.isInvalid())
- return;
- DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
- Attrs.clearListOnly();
- }
- void DiagnoseProhibitedAttributes(const SourceRange &Range,
- SourceLocation FixItLoc);
- // Forbid C++11 and C2x attributes that appear on certain syntactic locations
- // which standard permits but we don't supported yet, for example, attributes
- // appertain to decl specifiers.
- void ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
- unsigned DiagID,
- bool DiagnoseEmptyAttrs = false);
- /// Skip C++11 and C2x attributes and return the end location of the
- /// last one.
- /// \returns SourceLocation() if there are no attributes.
- SourceLocation SkipCXX11Attributes();
- /// Diagnose and skip C++11 and C2x attributes that appear in syntactic
- /// locations where attributes are not allowed.
- void DiagnoseAndSkipCXX11Attributes();
- /// Emit warnings for C++11 and C2x attributes that are in a position that
- /// clang accepts as an extension.
- void DiagnoseCXX11AttributeExtension(ParsedAttributesWithRange &Attrs);
- /// Parses syntax-generic attribute arguments for attributes which are
- /// known to the implementation, and adds them to the given ParsedAttributes
- /// list with the given attribute syntax. Returns the number of arguments
- /// parsed for the attribute.
- unsigned
- ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs, SourceLocation *EndLoc,
- IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
- enum ParseAttrKindMask {
- PAKM_GNU = 1 << 0,
- PAKM_Declspec = 1 << 1,
- PAKM_CXX11 = 1 << 2,
- };
- /// \brief Parse attributes based on what syntaxes are desired, allowing for
- /// the order to vary. e.g. with PAKM_GNU | PAKM_Declspec:
- /// __attribute__((...)) __declspec(...) __attribute__((...)))
- /// Note that Microsoft attributes (spelled with single square brackets) are
- /// not supported by this because of parsing ambiguities with other
- /// constructs.
- ///
- /// There are some attribute parse orderings that should not be allowed in
- /// arbitrary order. e.g.,
- ///
- /// [[]] __attribute__(()) int i; // OK
- /// __attribute__(()) [[]] int i; // Not OK
- ///
- /// Such situations should use the specific attribute parsing functionality.
- void ParseAttributes(unsigned WhichAttrKinds,
- ParsedAttributesWithRange &Attrs,
- SourceLocation *End = nullptr,
- LateParsedAttrList *LateAttrs = nullptr);
- void ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
- SourceLocation *End = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseAttributes(WhichAttrKinds, AttrsWithRange, End, LateAttrs);
- Attrs.takeAllFrom(AttrsWithRange);
- }
- /// \brief Possibly parse attributes based on what syntaxes are desired,
- /// allowing for the order to vary.
- bool MaybeParseAttributes(unsigned WhichAttrKinds,
- ParsedAttributesWithRange &Attrs,
- SourceLocation *End = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec) ||
- (standardAttributesAllowed() && isCXX11AttributeSpecifier())) {
- ParseAttributes(WhichAttrKinds, Attrs, End, LateAttrs);
- return true;
- }
- return false;
- }
- bool MaybeParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
- SourceLocation *End = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec) ||
- (standardAttributesAllowed() && isCXX11AttributeSpecifier())) {
- ParseAttributes(WhichAttrKinds, Attrs, End, LateAttrs);
- return true;
- }
- return false;
- }
- void MaybeParseGNUAttributes(Declarator &D,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.is(tok::kw___attribute)) {
- ParsedAttributes attrs(AttrFactory);
- SourceLocation endLoc;
- ParseGNUAttributes(attrs, &endLoc, LateAttrs, &D);
- D.takeAttributes(attrs, endLoc);
- }
- }
- /// Parses GNU-style attributes and returns them without source range
- /// information.
- ///
- /// This API is discouraged. Use the version that takes a
- /// ParsedAttributesWithRange instead.
- bool MaybeParseGNUAttributes(ParsedAttributes &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.is(tok::kw___attribute)) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseGNUAttributes(Attrs, EndLoc, LateAttrs);
- Attrs.takeAllFrom(AttrsWithRange);
- return true;
- }
- return false;
- }
- bool MaybeParseGNUAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.is(tok::kw___attribute)) {
- ParseGNUAttributes(Attrs, EndLoc, LateAttrs);
- return true;
- }
- return false;
- }
- /// Parses GNU-style attributes and returns them without source range
- /// information.
- ///
- /// This API is discouraged. Use the version that takes a
- /// ParsedAttributesWithRange instead.
- void ParseGNUAttributes(ParsedAttributes &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr,
- Declarator *D = nullptr) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseGNUAttributes(AttrsWithRange, EndLoc, LateAttrs, D);
- Attrs.takeAllFrom(AttrsWithRange);
- }
- void ParseGNUAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr,
- Declarator *D = nullptr);
- void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs, SourceLocation *EndLoc,
- IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax, Declarator *D);
- IdentifierLoc *ParseIdentifierLoc();
- unsigned
- ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs, SourceLocation *EndLoc,
- IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
- void ReplayOpenMPAttributeTokens(CachedTokens &OpenMPTokens) {
- // If parsing the attributes found an OpenMP directive, emit those tokens
- // to the parse stream now.
- if (!OpenMPTokens.empty()) {
- PP.EnterToken(Tok, /*IsReinject*/ true);
- PP.EnterTokenStream(OpenMPTokens, /*DisableMacroExpansion*/ true,
- /*IsReinject*/ true);
- ConsumeAnyToken(/*ConsumeCodeCompletionTok*/ true);
- }
- }
- void MaybeParseCXX11Attributes(Declarator &D) {
- if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
- ParsedAttributesWithRange attrs(AttrFactory);
- SourceLocation endLoc;
- ParseCXX11Attributes(attrs, &endLoc);
- D.takeAttributes(attrs, endLoc);
- }
- }
- bool MaybeParseCXX11Attributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr) {
- if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
- ParsedAttributesWithRange attrsWithRange(AttrFactory);
- ParseCXX11Attributes(attrsWithRange, endLoc);
- attrs.takeAllFrom(attrsWithRange);
- return true;
- }
- return false;
- }
- bool MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *endLoc = nullptr,
- bool OuterMightBeMessageSend = false) {
- if (standardAttributesAllowed() &&
- isCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) {
- ParseCXX11Attributes(attrs, endLoc);
- return true;
- }
- return false;
- }
- void ParseOpenMPAttributeArgs(IdentifierInfo *AttrName,
- CachedTokens &OpenMPTokens);
- void ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
- CachedTokens &OpenMPTokens,
- SourceLocation *EndLoc = nullptr);
- void ParseCXX11AttributeSpecifier(ParsedAttributes &Attrs,
- SourceLocation *EndLoc = nullptr) {
- CachedTokens OpenMPTokens;
- ParseCXX11AttributeSpecifierInternal(Attrs, OpenMPTokens, EndLoc);
- ReplayOpenMPAttributeTokens(OpenMPTokens);
- }
- void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *EndLoc = nullptr);
- /// Parses a C++11 (or C2x)-style attribute argument list. Returns true
- /// if this results in adding an attribute to the ParsedAttributes list.
- bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs, SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- CachedTokens &OpenMPTokens);
- IdentifierInfo *TryParseCXX11AttributeIdentifier(
- SourceLocation &Loc,
- Sema::AttributeCompletion Completion = Sema::AttributeCompletion::None,
- const IdentifierInfo *EnclosingScope = nullptr);
- void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr) {
- if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
- ParseMicrosoftAttributes(attrs, endLoc);
- }
- void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs);
- void ParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr);
- bool MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
- SourceLocation *End = nullptr) {
- const auto &LO = getLangOpts();
- if (LO.DeclSpecKeyword && Tok.is(tok::kw___declspec)) {
- ParseMicrosoftDeclSpecs(Attrs, End);
- return true;
- }
- return false;
- }
- void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
- SourceLocation *End = nullptr);
- bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs);
- void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
- void DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
- SourceLocation SkipExtendedMicrosoftTypeAttributes();
- void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
- void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
- void ParseOpenCLKernelAttributes(ParsedAttributes &attrs);
- void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
- void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs);
- VersionTuple ParseVersionTuple(SourceRange &Range);
- void ParseAvailabilityAttribute(IdentifierInfo &Availability,
- SourceLocation AvailabilityLoc,
- ParsedAttributes &attrs,
- SourceLocation *endLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
- Optional<AvailabilitySpec> ParseAvailabilitySpec();
- ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
- void ParseExternalSourceSymbolAttribute(IdentifierInfo &ExternalSourceSymbol,
- SourceLocation Loc,
- ParsedAttributes &Attrs,
- SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
- void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
- SourceLocation ObjCBridgeRelatedLoc,
- ParsedAttributes &attrs,
- SourceLocation *endLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
- void ParseSwiftNewTypeAttribute(IdentifierInfo &AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs,
- SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
- void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
- SourceLocation AttrNameLoc,
- ParsedAttributes &Attrs,
- SourceLocation *EndLoc,
- IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
- void
- ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
- SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
- SourceLocation *EndLoc, IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax);
- void ParseTypeofSpecifier(DeclSpec &DS);
- SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
- void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
- SourceLocation StartLoc,
- SourceLocation EndLoc);
- void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
- void ParseAtomicSpecifier(DeclSpec &DS);
- ExprResult ParseAlignArgument(SourceLocation Start,
- SourceLocation &EllipsisLoc);
- void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
- SourceLocation *endLoc = nullptr);
- ExprResult ParseExtIntegerArgument();
- VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
- VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
- return isCXX11VirtSpecifier(Tok);
- }
- void ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, bool IsInterface,
- SourceLocation FriendLoc);
- bool isCXX11FinalKeyword() const;
- bool isClassCompatibleKeyword() const;
- /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
- /// enter a new C++ declarator scope and exit it when the function is
- /// finished.
- class DeclaratorScopeObj {
- Parser &P;
- CXXScopeSpec &SS;
- bool EnteredScope;
- bool CreatedScope;
- public:
- DeclaratorScopeObj(Parser &p, CXXScopeSpec &ss)
- : P(p), SS(ss), EnteredScope(false), CreatedScope(false) {}
- void EnterDeclaratorScope() {
- assert(!EnteredScope && "Already entered the scope!");
- assert(SS.isSet() && "C++ scope was not set!");
- CreatedScope = true;
- P.EnterScope(0); // Not a decl scope.
- if (!P.Actions.ActOnCXXEnterDeclaratorScope(P.getCurScope(), SS))
- EnteredScope = true;
- }
- ~DeclaratorScopeObj() {
- if (EnteredScope) {
- assert(SS.isSet() && "C++ scope was cleared ?");
- P.Actions.ActOnCXXExitDeclaratorScope(P.getCurScope(), SS);
- }
- if (CreatedScope)
- P.ExitScope();
- }
- };
- /// ParseDeclarator - Parse and verify a newly-initialized declarator.
- void ParseDeclarator(Declarator &D);
- /// A function that parses a variant of direct-declarator.
- typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
- void ParseDeclaratorInternal(Declarator &D,
- DirectDeclParseFunction DirectDeclParser);
- enum AttrRequirements {
- AR_NoAttributesParsed = 0, ///< No attributes are diagnosed.
- AR_GNUAttributesParsedAndRejected = 1 << 0, ///< Diagnose GNU attributes.
- AR_GNUAttributesParsed = 1 << 1,
- AR_CXX11AttributesParsed = 1 << 2,
- AR_DeclspecAttributesParsed = 1 << 3,
- AR_AllAttributesParsed = AR_GNUAttributesParsed |
- AR_CXX11AttributesParsed |
- AR_DeclspecAttributesParsed,
- AR_VendorAttributesParsed = AR_GNUAttributesParsed |
- AR_DeclspecAttributesParsed
- };
- void ParseTypeQualifierListOpt(
- DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
- bool AtomicAllowed = true, bool IdentifierRequired = false,
- Optional<llvm::function_ref<void()>> CodeCompletionHandler = None);
- void ParseDirectDeclarator(Declarator &D);
- void ParseDecompositionDeclarator(Declarator &D);
- void ParseParenDeclarator(Declarator &D);
- void ParseFunctionDeclarator(Declarator &D,
- ParsedAttributes &attrs,
- BalancedDelimiterTracker &Tracker,
- bool IsAmbiguous,
- bool RequiresArg = false);
- void InitCXXThisScopeForDeclaratorIfRelevant(
- const Declarator &D, const DeclSpec &DS,
- llvm::Optional<Sema::CXXThisScopeRAII> &ThisScope);
- bool ParseRefQualifier(bool &RefQualifierIsLValueRef,
- SourceLocation &RefQualifierLoc);
- bool isFunctionDeclaratorIdentifierList();
- void ParseFunctionDeclaratorIdentifierList(
- Declarator &D,
- SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
- void ParseParameterDeclarationClause(
- DeclaratorContext DeclaratorContext,
- ParsedAttributes &attrs,
- SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
- SourceLocation &EllipsisLoc);
- void ParseBracketDeclarator(Declarator &D);
- void ParseMisplacedBracketDeclarator(Declarator &D);
- //===--------------------------------------------------------------------===//
- // C++ 7: Declarations [dcl.dcl]
- /// The kind of attribute specifier we have found.
- enum CXX11AttributeKind {
- /// This is not an attribute specifier.
- CAK_NotAttributeSpecifier,
- /// This should be treated as an attribute-specifier.
- CAK_AttributeSpecifier,
- /// The next tokens are '[[', but this is not an attribute-specifier. This
- /// is ill-formed by C++11 [dcl.attr.grammar]p6.
- CAK_InvalidAttributeSpecifier
- };
- CXX11AttributeKind
- isCXX11AttributeSpecifier(bool Disambiguate = false,
- bool OuterMightBeMessageSend = false);
- void DiagnoseUnexpectedNamespace(NamedDecl *Context);
- DeclGroupPtrTy ParseNamespace(DeclaratorContext Context,
- SourceLocation &DeclEnd,
- SourceLocation InlineLoc = SourceLocation());
- struct InnerNamespaceInfo {
- SourceLocation NamespaceLoc;
- SourceLocation InlineLoc;
- SourceLocation IdentLoc;
- IdentifierInfo *Ident;
- };
- using InnerNamespaceInfoList = llvm::SmallVector<InnerNamespaceInfo, 4>;
- void ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
- unsigned int index, SourceLocation &InlineLoc,
- ParsedAttributes &attrs,
- BalancedDelimiterTracker &Tracker);
- Decl *ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context);
- Decl *ParseExportDeclaration();
- DeclGroupPtrTy ParseUsingDirectiveOrDeclaration(
- DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
- SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs);
- Decl *ParseUsingDirective(DeclaratorContext Context,
- SourceLocation UsingLoc,
- SourceLocation &DeclEnd,
- ParsedAttributes &attrs);
- struct UsingDeclarator {
- SourceLocation TypenameLoc;
- CXXScopeSpec SS;
- UnqualifiedId Name;
- SourceLocation EllipsisLoc;
- void clear() {
- TypenameLoc = EllipsisLoc = SourceLocation();
- SS.clear();
- Name.clear();
- }
- };
- bool ParseUsingDeclarator(DeclaratorContext Context, UsingDeclarator &D);
- DeclGroupPtrTy ParseUsingDeclaration(DeclaratorContext Context,
- const ParsedTemplateInfo &TemplateInfo,
- SourceLocation UsingLoc,
- SourceLocation &DeclEnd,
- ParsedAttributesWithRange &Attrs,
- AccessSpecifier AS = AS_none);
- Decl *ParseAliasDeclarationAfterDeclarator(
- const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
- UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,
- ParsedAttributes &Attrs, Decl **OwnedType = nullptr);
- Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
- Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
- SourceLocation AliasLoc, IdentifierInfo *Alias,
- SourceLocation &DeclEnd);
- //===--------------------------------------------------------------------===//
- // C++ 9: classes [class] and C structs/unions.
- bool isValidAfterTypeSpecifier(bool CouldBeBitfield);
- void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
- DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS, bool EnteringContext,
- DeclSpecContext DSC,
- ParsedAttributesWithRange &Attributes);
- void SkipCXXMemberSpecification(SourceLocation StartLoc,
- SourceLocation AttrFixitLoc,
- unsigned TagType,
- Decl *TagDecl);
- void ParseCXXMemberSpecification(SourceLocation StartLoc,
- SourceLocation AttrFixitLoc,
- ParsedAttributesWithRange &Attrs,
- unsigned TagType,
- Decl *TagDecl);
- ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
- SourceLocation &EqualLoc);
- bool
- ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
- VirtSpecifiers &VS,
- ExprResult &BitfieldSize,
- LateParsedAttrList &LateAttrs);
- void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D,
- VirtSpecifiers &VS);
- DeclGroupPtrTy ParseCXXClassMemberDeclaration(
- AccessSpecifier AS, ParsedAttributes &Attr,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
- DeclGroupPtrTy ParseCXXClassMemberDeclarationWithPragmas(
- AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs,
- DeclSpec::TST TagType, Decl *Tag);
- void ParseConstructorInitializer(Decl *ConstructorDecl);
- MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
- void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
- Decl *ThisDecl);
- //===--------------------------------------------------------------------===//
- // C++ 10: Derived classes [class.derived]
- TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
- SourceLocation &EndLocation);
- void ParseBaseClause(Decl *ClassDecl);
- BaseResult ParseBaseSpecifier(Decl *ClassDecl);
- AccessSpecifier getAccessSpecifierIfPresent() const;
- bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
- ParsedType ObjectType,
- bool ObjectHadErrors,
- SourceLocation TemplateKWLoc,
- IdentifierInfo *Name,
- SourceLocation NameLoc,
- bool EnteringContext,
- UnqualifiedId &Id,
- bool AssumeTemplateId);
- bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
- ParsedType ObjectType,
- UnqualifiedId &Result);
- //===--------------------------------------------------------------------===//
- // OpenMP: Directives and clauses.
- /// Parse clauses for '#pragma omp declare simd'.
- DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
- CachedTokens &Toks,
- SourceLocation Loc);
- /// Parse a property kind into \p TIProperty for the selector set \p Set and
- /// selector \p Selector.
- void parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
- llvm::omp::TraitSet Set,
- llvm::omp::TraitSelector Selector,
- llvm::StringMap<SourceLocation> &Seen);
- /// Parse a selector kind into \p TISelector for the selector set \p Set.
- void parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
- llvm::omp::TraitSet Set,
- llvm::StringMap<SourceLocation> &Seen);
- /// Parse a selector set kind into \p TISet.
- void parseOMPTraitSetKind(OMPTraitSet &TISet,
- llvm::StringMap<SourceLocation> &Seen);
- /// Parses an OpenMP context property.
- void parseOMPContextProperty(OMPTraitSelector &TISelector,
- llvm::omp::TraitSet Set,
- llvm::StringMap<SourceLocation> &Seen);
- /// Parses an OpenMP context selector.
- void parseOMPContextSelector(OMPTraitSelector &TISelector,
- llvm::omp::TraitSet Set,
- llvm::StringMap<SourceLocation> &SeenSelectors);
- /// Parses an OpenMP context selector set.
- void parseOMPContextSelectorSet(OMPTraitSet &TISet,
- llvm::StringMap<SourceLocation> &SeenSets);
- /// Parses OpenMP context selectors.
- bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI);
- /// Parse an 'append_args' clause for '#pragma omp declare variant'.
- bool parseOpenMPAppendArgs(
- SmallVectorImpl<OMPDeclareVariantAttr::InteropType> &InterOpTypes);
- /// Parse a `match` clause for an '#pragma omp declare variant'. Return true
- /// if there was an error.
- bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI,
- OMPTraitInfo *ParentTI);
- /// Parse clauses for '#pragma omp declare variant'.
- void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
- SourceLocation Loc);
- /// Parse 'omp [begin] assume[s]' directive.
- void ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
- SourceLocation Loc);
- /// Parse 'omp end assumes' directive.
- void ParseOpenMPEndAssumesDirective(SourceLocation Loc);
- /// Parse clauses for '#pragma omp [begin] declare target'.
- void ParseOMPDeclareTargetClauses(Sema::DeclareTargetContextInfo &DTCI);
- /// Parse '#pragma omp end declare target'.
- void ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
- OpenMPDirectiveKind EndDKind,
- SourceLocation Loc);
- /// Skip tokens until a `annot_pragma_openmp_end` was found. Emit a warning if
- /// it is not the current token.
- void skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind);
- /// Check the \p FoundKind against the \p ExpectedKind, if not issue an error
- /// that the "end" matching the "begin" directive of kind \p BeginKind was not
- /// found. Finally, if the expected kind was found or if \p SkipUntilOpenMPEnd
- /// is set, skip ahead using the helper `skipUntilPragmaOpenMPEnd`.
- void parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
- OpenMPDirectiveKind ExpectedKind,
- OpenMPDirectiveKind FoundKind,
- SourceLocation MatchingLoc,
- SourceLocation FoundLoc,
- bool SkipUntilOpenMPEnd);
- /// Parses declarative OpenMP directives.
- DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
- AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
- bool Delayed = false, DeclSpec::TST TagType = DeclSpec::TST_unspecified,
- Decl *TagDecl = nullptr);
- /// Parse 'omp declare reduction' construct.
- DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
- /// Parses initializer for provided omp_priv declaration inside the reduction
- /// initializer.
- void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);
- /// Parses 'omp declare mapper' directive.
- DeclGroupPtrTy ParseOpenMPDeclareMapperDirective(AccessSpecifier AS);
- /// Parses variable declaration in 'omp declare mapper' directive.
- TypeResult parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
- DeclarationName &Name,
- AccessSpecifier AS = AS_none);
- /// Tries to parse cast part of OpenMP array shaping operation:
- /// '[' expression ']' { '[' expression ']' } ')'.
- bool tryParseOpenMPArrayShapingCastPart();
- /// Parses simple list of variables.
- ///
- /// \param Kind Kind of the directive.
- /// \param Callback Callback function to be called for the list elements.
- /// \param AllowScopeSpecifier true, if the variables can have fully
- /// qualified names.
- ///
- bool ParseOpenMPSimpleVarList(
- OpenMPDirectiveKind Kind,
- const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
- Callback,
- bool AllowScopeSpecifier);
- /// Parses declarative or executable directive.
- ///
- /// \param StmtCtx The context in which we're parsing the directive.
- StmtResult
- ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx);
- /// Parses clause of kind \a CKind for directive of a kind \a Kind.
- ///
- /// \param DKind Kind of current directive.
- /// \param CKind Kind of current clause.
- /// \param FirstClause true, if this is the first clause of a kind \a CKind
- /// in current directive.
- ///
- OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind,
- OpenMPClauseKind CKind, bool FirstClause);
- /// Parses clause with a single expression of a kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- /// \param ParseOnly true to skip the clause's semantic actions and return
- /// nullptr.
- ///
- OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
- bool ParseOnly);
- /// Parses simple clause of a kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- /// \param ParseOnly true to skip the clause's semantic actions and return
- /// nullptr.
- ///
- OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind, bool ParseOnly);
- /// Parses indirect clause
- /// \param ParseOnly true to skip the clause's semantic actions and return
- // false;
- bool ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI,
- bool ParseOnly);
- /// Parses clause with a single expression and an additional argument
- /// of a kind \a Kind.
- ///
- /// \param DKind Directive kind.
- /// \param Kind Kind of current clause.
- /// \param ParseOnly true to skip the clause's semantic actions and return
- /// nullptr.
- ///
- OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
- OpenMPClauseKind Kind,
- bool ParseOnly);
- /// Parses the 'sizes' clause of a '#pragma omp tile' directive.
- OMPClause *ParseOpenMPSizesClause();
- /// Parses clause without any additional arguments.
- ///
- /// \param Kind Kind of current clause.
- /// \param ParseOnly true to skip the clause's semantic actions and return
- /// nullptr.
- ///
- OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly = false);
- /// Parses clause with the list of variables of a kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- /// \param ParseOnly true to skip the clause's semantic actions and return
- /// nullptr.
- ///
- OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
- OpenMPClauseKind Kind, bool ParseOnly);
- /// Parses and creates OpenMP 5.0 iterators expression:
- /// <iterators> = 'iterator' '(' { [ <iterator-type> ] identifier =
- /// <range-specification> }+ ')'
- ExprResult ParseOpenMPIteratorsExpr();
- /// Parses allocators and traits in the context of the uses_allocator clause.
- /// Expected format:
- /// '(' { <allocator> [ '(' <allocator_traits> ')' ] }+ ')'
- OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind);
- /// Parses clause with an interop variable of kind \a Kind.
- ///
- /// \param Kind Kind of current clause.
- /// \param ParseOnly true to skip the clause's semantic actions and return
- /// nullptr.
- //
- OMPClause *ParseOpenMPInteropClause(OpenMPClauseKind Kind, bool ParseOnly);
- public:
- /// Parses simple expression in parens for single-expression clauses of OpenMP
- /// constructs.
- /// \param RLoc Returned location of right paren.
- ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc,
- bool IsAddressOfOperand = false);
- /// Data used for parsing list of variables in OpenMP clauses.
- struct OpenMPVarListDataTy {
- Expr *DepModOrTailExpr = nullptr;
- SourceLocation ColonLoc;
- SourceLocation RLoc;
- CXXScopeSpec ReductionOrMapperIdScopeSpec;
- DeclarationNameInfo ReductionOrMapperId;
- int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or
- ///< lastprivate clause.
- SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
- MapTypeModifiers;
- SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
- MapTypeModifiersLoc;
- SmallVector<OpenMPMotionModifierKind, NumberOfOMPMotionModifiers>
- MotionModifiers;
- SmallVector<SourceLocation, NumberOfOMPMotionModifiers> MotionModifiersLoc;
- bool IsMapTypeImplicit = false;
- SourceLocation ExtraModifierLoc;
- };
- /// Parses clauses with list.
- bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind,
- SmallVectorImpl<Expr *> &Vars,
- OpenMPVarListDataTy &Data);
- bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
- bool ObjectHadErrors, bool EnteringContext,
- bool AllowDestructorName, bool AllowConstructorName,
- bool AllowDeductionGuide,
- SourceLocation *TemplateKWLoc, UnqualifiedId &Result);
- /// Parses the mapper modifier in map, to, and from clauses.
- bool parseMapperModifier(OpenMPVarListDataTy &Data);
- /// Parses map-type-modifiers in map clause.
- /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
- /// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
- bool parseMapTypeModifiers(OpenMPVarListDataTy &Data);
- private:
- //===--------------------------------------------------------------------===//
- // C++ 14: Templates [temp]
- // C++ 14.1: Template Parameters [temp.param]
- Decl *ParseDeclarationStartingWithTemplate(DeclaratorContext Context,
- SourceLocation &DeclEnd,
- ParsedAttributes &AccessAttrs,
- AccessSpecifier AS = AS_none);
- Decl *ParseTemplateDeclarationOrSpecialization(DeclaratorContext Context,
- SourceLocation &DeclEnd,
- ParsedAttributes &AccessAttrs,
- AccessSpecifier AS);
- Decl *ParseSingleDeclarationAfterTemplate(
- DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
- ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
- ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none);
- bool ParseTemplateParameters(MultiParseScope &TemplateScopes, unsigned Depth,
- SmallVectorImpl<NamedDecl *> &TemplateParams,
- SourceLocation &LAngleLoc,
- SourceLocation &RAngleLoc);
- bool ParseTemplateParameterList(unsigned Depth,
- SmallVectorImpl<NamedDecl*> &TemplateParams);
- TPResult isStartOfTemplateTypeParameter();
- NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position);
- NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position);
- NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
- NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
- bool isTypeConstraintAnnotation();
- bool TryAnnotateTypeConstraint();
- void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
- SourceLocation CorrectLoc,
- bool AlreadyHasEllipsis,
- bool IdentifierHasName);
- void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
- Declarator &D);
- // C++ 14.3: Template arguments [temp.arg]
- typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
- bool ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,
- SourceLocation &RAngleLoc,
- bool ConsumeLastToken,
- bool ObjCGenericList);
- bool ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
- SourceLocation &LAngleLoc,
- TemplateArgList &TemplateArgs,
- SourceLocation &RAngleLoc,
- TemplateTy NameHint = nullptr);
- bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
- CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- UnqualifiedId &TemplateName,
- bool AllowTypeAnnotation = true,
- bool TypeConstraint = false);
- void AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
- bool IsClassName = false);
- bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
- TemplateTy Template, SourceLocation OpenLoc);
- ParsedTemplateArgument ParseTemplateTemplateArgument();
- ParsedTemplateArgument ParseTemplateArgument();
- Decl *ParseExplicitInstantiation(DeclaratorContext Context,
- SourceLocation ExternLoc,
- SourceLocation TemplateLoc,
- SourceLocation &DeclEnd,
- ParsedAttributes &AccessAttrs,
- AccessSpecifier AS = AS_none);
- // C++2a: Template, concept definition [temp]
- Decl *
- ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
- SourceLocation &DeclEnd);
- //===--------------------------------------------------------------------===//
- // Modules
- DeclGroupPtrTy ParseModuleDecl(bool IsFirstDecl);
- Decl *ParseModuleImport(SourceLocation AtLoc);
- bool parseMisplacedModuleImport();
- bool tryParseMisplacedModuleImport() {
- tok::TokenKind Kind = Tok.getKind();
- if (Kind == tok::annot_module_begin || Kind == tok::annot_module_end ||
- Kind == tok::annot_module_include)
- return parseMisplacedModuleImport();
- return false;
- }
- bool ParseModuleName(
- SourceLocation UseLoc,
- SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
- bool IsImport);
- //===--------------------------------------------------------------------===//
- // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
- ExprResult ParseTypeTrait();
- //===--------------------------------------------------------------------===//
- // Embarcadero: Arary and Expression Traits
- ExprResult ParseArrayTypeTrait();
- ExprResult ParseExpressionTrait();
- //===--------------------------------------------------------------------===//
- // Preprocessor code-completion pass-through
- void CodeCompleteDirective(bool InConditional) override;
- void CodeCompleteInConditionalExclusion() override;
- void CodeCompleteMacroName(bool IsDefinition) override;
- void CodeCompletePreprocessorExpression() override;
- void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
- unsigned ArgumentIndex) override;
- void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) override;
- void CodeCompleteNaturalLanguage() override;
- class GNUAsmQualifiers {
- unsigned Qualifiers = AQ_unspecified;
- public:
- enum AQ {
- AQ_unspecified = 0,
- AQ_volatile = 1,
- AQ_inline = 2,
- AQ_goto = 4,
- };
- static const char *getQualifierName(AQ Qualifier);
- bool setAsmQualifier(AQ Qualifier);
- inline bool isVolatile() const { return Qualifiers & AQ_volatile; };
- inline bool isInline() const { return Qualifiers & AQ_inline; };
- inline bool isGoto() const { return Qualifiers & AQ_goto; }
- };
- bool isGCCAsmStatement(const Token &TokAfterAsm) const;
- bool isGNUAsmQualifier(const Token &TokAfterAsm) const;
- GNUAsmQualifiers::AQ getGNUAsmQualifier(const Token &Tok) const;
- bool parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ);
- };
- } // end namespace clang
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|