23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/SmallString.h"
25 using namespace clang;
31 bool Parser::MayBeDesignationStart() {
76 RevertingTentativeParsingAction Tentative(*
this);
79 LambdaIntroducerTentativeParse ParseResult;
80 if (ParseLambdaIntroducer(Intro, &ParseResult)) {
86 switch (ParseResult) {
87 case LambdaIntroducerTentativeParse::Success:
88 case LambdaIntroducerTentativeParse::Incomplete:
94 case LambdaIntroducerTentativeParse::MessageSend:
95 case LambdaIntroducerTentativeParse::Invalid:
106 return Tok.
is(tok::equal);
117 P.Diag(
Loc, diag::ext_gnu_missing_equal_designator);
119 P.Diag(
Loc, diag::err_expected_equal_designator);
164 ExprResult Parser::ParseInitializerWithPotentialDesignator(
165 DesignatorCompletionInfo DesignatorCompletion) {
170 if (Tok.
is(tok::identifier)) {
174 llvm::raw_svector_ostream(NewSyntax) <<
'.' << FieldName->
getName()
179 assert(Tok.
is(tok::colon) &&
"MayBeDesignationStart not working properly!");
182 Diag(NameLoc, diag::ext_gnu_old_style_field_designator)
190 Tok.
getLocation(), DesignatorCompletion.PreferredBaseType, D);
201 while (Tok.
is(tok::period) || Tok.
is(tok::l_square)) {
202 if (Tok.
is(tok::period)) {
206 if (Tok.
is(tok::code_completion)) {
209 DesignatorCompletion.PreferredBaseType,
210 DesignatorCompletion.InitExprs, Desig);
213 if (Tok.
isNot(tok::identifier)) {
225 assert(Tok.
is(tok::l_square) &&
"Unexpected token!");
262 return ParseAssignmentExprWithObjCMessageExprStart(
269 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
278 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
298 NextToken().is(tok::period), ReceiverType)) {
301 return ParseAssignmentExprWithObjCMessageExprStart(
313 if (Tok.
is(tok::less)) {
316 = parseObjCTypeArgsAndProtocolQualifiers(IILoc, ReceiverType,
324 ReceiverType = NewReceiverType.
get();
327 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
360 Tok.
isNot(tok::r_square)) {
362 return ParseAssignmentExprWithObjCMessageExprStart(
367 if (Tok.
isNot(tok::ellipsis)) {
372 Diag(Tok, diag::ext_gnu_array_range);
376 if (RHS.isInvalid()) {
381 Idx.
get(), RHS.get(), StartLoc, EllipsisLoc));
386 T.getCloseLocation());
393 assert(!Desig.
empty() &&
"Designator is empty?");
396 if (Tok.
is(tok::equal)) {
399 Tok.
getLocation(), DesignatorCompletion.PreferredBaseType, Desig);
409 Tok.
getLocation(), DesignatorCompletion.PreferredBaseType, Desig);
411 ParseBraceInitializer());
421 Diag(Tok, diag::ext_gnu_missing_equal_designator)
424 true, ParseInitializer());
427 Diag(Tok, diag::err_expected_equal_designator);
452 ExprVector InitExprs;
454 if (Tok.
is(tok::r_brace)) {
458 ? diag::warn_c23_compat_empty_initializer
459 : diag::ext_c_empty_initializer);
462 return Actions.
ActOnInitList(LBraceLoc, std::nullopt, ConsumeBrace());
469 bool InitExprsOk =
true;
470 QualType LikelyType = PreferredType.
get(
T.getOpenLocation());
471 DesignatorCompletionInfo DesignatorCompletion{InitExprs, LikelyType};
472 bool CalledSignatureHelp =
false;
473 auto RunSignatureHelp = [&] {
478 InitExprs,
T.getOpenLocation(),
true);
479 CalledSignatureHelp =
true;
480 return PreferredType;
484 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
487 if (
getLangOpts().MicrosoftExt && (Tok.
is(tok::kw___if_exists) ||
488 Tok.
is(tok::kw___if_not_exists))) {
489 if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
490 if (Tok.
isNot(tok::comma))
break;
493 if (Tok.
is(tok::r_brace))
break;
502 if (MayBeDesignationStart())
503 SubElt = ParseInitializerWithPotentialDesignator(DesignatorCompletion);
505 SubElt = ParseInitializer();
507 if (Tok.
is(tok::ellipsis))
514 InitExprs.push_back(SubElt.
get());
526 if (Tok.
isNot(tok::comma)) {
533 if (Tok.
isNot(tok::comma))
break;
539 if (Tok.
is(tok::r_brace))
break;
542 bool closed = !
T.consumeClose();
544 if (InitExprsOk && closed)
546 T.getCloseLocation());
554 bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
556 bool trailingComma =
false;
557 IfExistsCondition Result;
558 if (ParseMicrosoftIfExistsCondition(Result))
562 if (
Braces.consumeOpen()) {
563 Diag(Tok, diag::err_expected) << tok::l_brace;
567 switch (Result.Behavior) {
573 Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
574 << Result.IsIfExists;
583 DesignatorCompletionInfo DesignatorCompletion{
585 PreferredType.get(
Braces.getOpenLocation()),
587 while (!isEofOrEom()) {
588 trailingComma =
false;
592 if (MayBeDesignationStart())
593 SubElt = ParseInitializerWithPotentialDesignator(DesignatorCompletion);
595 SubElt = ParseInitializer();
597 if (Tok.
is(tok::ellipsis))
602 InitExprs.push_back(SubElt.
get());
606 if (Tok.
is(tok::comma)) {
608 trailingComma =
true;
611 if (Tok.
is(tok::r_brace))
617 return !trailingComma;
static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, Designation &Desig)
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
Defines the clang::TokenKind enum and support functions.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Designation - Represent a full designation, which is a sequence of designators.
const Designator & getDesignator(unsigned Idx) const
unsigned getNumDesignators() const
void AddDesignator(Designator D)
AddDesignator - Add a designator to the end of this list.
bool isArrayDesignator() const
static Designator CreateArrayRangeDesignator(Expr *Start, Expr *End, SourceLocation LBracketLoc, SourceLocation EllipsisLoc)
Creates a GNU array-range designator.
static Designator CreateArrayDesignator(Expr *Index, SourceLocation LBracketLoc)
Creates an array designator.
void setRBracketLoc(SourceLocation RBracketLoc) const
bool isArrayRangeDesignator() const
static Designator CreateFieldDesignator(const IdentifierInfo *FieldName, SourceLocation DotLoc, SourceLocation FieldLoc)
Creates a field designator.
RAII object that enters a new expression evaluation context.
This represents one expression.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
static OpaquePtr getFromOpaquePtr(void *P)
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Scope * getCurScope() const
ExprResult ParseConstantExpression()
const LangOptions & getLangOpts() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
void enterDesignatedInitializer(SourceLocation Tok, QualType BaseType, const Designation &D)
Handles e.g. BaseType{ .D = Tok...
QualType get(SourceLocation Tok) const
Get the expected type associated with this location, if any.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
const LangOptions & getLangOpts() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
void CodeCompleteDesignator(const QualType BaseType, llvm::ArrayRef< Expr * > InitExprs, const Designation &D)
Trigger code completion for a record of BaseType.
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
@ ObjCClassMessage
The message is a class message, and the identifier is a type name.
@ ObjCInstanceMessage
The message is an instance message.
@ ObjCSuperMessage
The message is sent to 'super'.
ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation EqualOrColonLoc, bool GNUSyntax, ExprResult Init)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
ExprResult ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, SourceLocation RBraceLoc)
SemaCodeCompletion & CodeCompletion()
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
IdentifierInfo * getIdentifierInfo() const
bool isNot(tok::TokenKind K) const
QualType getCanonicalTypeInternal() const
The JSON file list parser is used to communicate input to InstallAPI.
ActionResult< Expr * > ExprResult
const FunctionProtoType * T
@ Braces
New-expression has a C++11 list-initializer.
Represents a complete lambda introducer.