23#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/SmallString.h"
31bool 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);
164ExprResult 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);
432 assert(Tok.
getKind() == tok::annot_embed);
438 if (
Data->BinaryData.size() == 1) {
443 auto CreateStringLiteralFromStringRef = [&](StringRef Str,
QualType Ty) {
444 llvm::APSInt ArraySize =
449 false, ArrayTy, StartLoc);
452 StringLiteral *BinaryDataArg = CreateStringLiteralFromStringRef(
480 ExprVector InitExprs;
482 if (Tok.
is(tok::r_brace)) {
486 ? diag::warn_c23_compat_empty_initializer
487 : diag::ext_c_empty_initializer);
490 return Actions.
ActOnInitList(LBraceLoc, std::nullopt, ConsumeBrace());
497 bool InitExprsOk =
true;
498 QualType LikelyType = PreferredType.
get(
T.getOpenLocation());
499 DesignatorCompletionInfo DesignatorCompletion{InitExprs, LikelyType};
500 bool CalledSignatureHelp =
false;
501 auto RunSignatureHelp = [&] {
506 InitExprs,
T.getOpenLocation(),
true);
507 CalledSignatureHelp =
true;
508 return PreferredType;
512 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
515 if (
getLangOpts().MicrosoftExt && (Tok.
is(tok::kw___if_exists) ||
516 Tok.
is(tok::kw___if_not_exists))) {
517 if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
518 if (Tok.
isNot(tok::comma))
break;
521 if (Tok.
is(tok::r_brace))
break;
530 if (MayBeDesignationStart())
531 SubElt = ParseInitializerWithPotentialDesignator(DesignatorCompletion);
532 else if (Tok.
getKind() == tok::annot_embed)
533 SubElt = createEmbedExpr();
535 SubElt = ParseInitializer();
537 if (Tok.
is(tok::ellipsis))
544 InitExprs.push_back(SubElt.
get());
556 if (Tok.
isNot(tok::comma)) {
563 if (Tok.
isNot(tok::comma))
break;
569 if (Tok.
is(tok::r_brace))
break;
572 bool closed = !
T.consumeClose();
574 if (InitExprsOk && closed)
576 T.getCloseLocation());
584bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
586 bool trailingComma =
false;
588 if (ParseMicrosoftIfExistsCondition(
Result))
592 if (
Braces.consumeOpen()) {
593 Diag(Tok, diag::err_expected) << tok::l_brace;
597 switch (
Result.Behavior) {
603 Diag(
Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
613 DesignatorCompletionInfo DesignatorCompletion{
615 PreferredType.get(
Braces.getOpenLocation()),
617 while (!isEofOrEom()) {
618 trailingComma =
false;
622 if (MayBeDesignationStart())
623 SubElt = ParseInitializerWithPotentialDesignator(DesignatorCompletion);
625 SubElt = ParseInitializer();
627 if (Tok.
is(tok::ellipsis))
632 InitExprs.push_back(SubElt.
get());
636 if (Tok.
is(tok::comma)) {
638 trailingComma =
true;
641 if (Tok.
is(tok::r_brace))
647 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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType UnsignedCharTy
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
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 IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
static OpaquePtr getFromOpaquePtr(void *P)
Parser - This implements a parser for the C family of languages.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
ExprResult ParseConstantExpression()
Scope * getCurScope() 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.
const LangOptions & getLangOpts() const
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
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)
ASTContext & getASTContext() const
SemaCodeCompletion & CodeCompletion()
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
ExprResult ActOnEmbedExpr(SourceLocation EmbedKeywordLoc, StringLiteral *BinaryData)
ExprResult ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, SourceLocation RBraceLoc)
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.
StringLiteral - This represents a string literal expression, e.g.
static StringLiteral * Create(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind, bool Pascal, QualType Ty, const SourceLocation *Loc, unsigned NumConcatenated)
This is the "fully general" constructor that allows representation of strings formed from multiple co...
IdentifierInfo * getIdentifierInfo() const
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)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
QualType getCanonicalTypeInternal() const
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
ActionResult< Expr * > ExprResult
const FunctionProtoType * T
@ Braces
New-expression has a C++11 list-initializer.
Helper class to shuttle information about #embed directives from the preprocessor to the parser throu...
Represents a complete lambda introducer.