19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/Support/raw_ostream.h"
21 using namespace clang;
27 bool Parser::MayBeDesignationStart() {
70 TentativeParsingAction Tentative(*
this);
73 bool SkippedInits =
false;
91 return Kind == tok::equal;
102 P.
Diag(Loc, diag::ext_gnu_missing_equal_designator);
104 P.
Diag(Loc, diag::err_expected_equal_designator);
131 ExprResult Parser::ParseInitializerWithPotentialDesignator() {
137 if (Tok.
is(tok::identifier)) {
141 llvm::raw_svector_ostream(NewSyntax) <<
'.' << FieldName->
getName()
146 assert(Tok.
is(tok::colon) &&
"MayBeDesignationStart not working properly!");
149 Diag(NameLoc, diag::ext_gnu_old_style_field_designator)
165 while (Tok.
is(tok::period) || Tok.
is(tok::l_square)) {
166 if (Tok.
is(tok::period)) {
170 if (Tok.
isNot(tok::identifier)) {
182 assert(Tok.
is(tok::l_square) &&
"Unexpected token!");
219 return ParseAssignmentExprWithObjCMessageExprStart(
226 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
235 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
245 Idx =
ExprResult(static_cast<Expr*>(TypeOrExpr));
255 NextToken().is(tok::period), ReceiverType)) {
258 return ParseAssignmentExprWithObjCMessageExprStart(
270 if (Tok.
is(tok::less)) {
273 = parseObjCTypeArgsAndProtocolQualifiers(IILoc, ReceiverType,
281 ReceiverType = NewReceiverType.
get();
284 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
317 Tok.
isNot(tok::r_square)) {
319 return ParseAssignmentExprWithObjCMessageExprStart(
324 if (Tok.
isNot(tok::ellipsis)) {
328 Diag(Tok, diag::ext_gnu_array_range);
332 if (RHS.isInvalid()) {
338 StartLoc, EllipsisLoc));
343 T.getCloseLocation());
350 assert(!Desig.
empty() &&
"Designator is empty?");
353 if (Tok.
is(tok::equal)) {
366 Diag(Tok, diag::ext_gnu_missing_equal_designator)
369 true, ParseInitializer());
372 Diag(Tok, diag::err_expected_equal_designator);
398 ExprVector InitExprs;
400 if (Tok.
is(tok::r_brace)) {
403 Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
408 bool InitExprsOk =
true;
412 if (
getLangOpts().MicrosoftExt && (Tok.
is(tok::kw___if_exists) ||
413 Tok.
is(tok::kw___if_not_exists))) {
414 if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
415 if (Tok.
isNot(tok::comma))
break;
418 if (Tok.
is(tok::r_brace))
break;
427 if (MayBeDesignationStart())
428 SubElt = ParseInitializerWithPotentialDesignator();
430 SubElt = ParseInitializer();
432 if (Tok.
is(tok::ellipsis))
439 InitExprs.push_back(SubElt.
get());
451 if (Tok.
isNot(tok::comma)) {
458 if (Tok.
isNot(tok::comma))
break;
464 if (Tok.
is(tok::r_brace))
break;
467 bool closed = !T.consumeClose();
469 if (InitExprsOk && closed)
471 T.getCloseLocation());
479 bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
481 bool trailingComma =
false;
483 if (ParseMicrosoftIfExistsCondition(Result))
487 if (Braces.consumeOpen()) {
488 Diag(Tok, diag::err_expected) << tok::l_brace;
492 switch (Result.Behavior) {
498 Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
499 << Result.IsIfExists;
507 while (!isEofOrEom()) {
508 trailingComma =
false;
512 if (MayBeDesignationStart())
513 SubElt = ParseInitializerWithPotentialDesignator();
515 SubElt = ParseInitializer();
517 if (Tok.
is(tok::ellipsis))
522 InitExprs.push_back(SubElt.
get());
526 if (Tok.
is(tok::comma)) {
528 trailingComma =
true;
531 if (Tok.
is(tok::r_brace))
535 Braces.consumeClose();
537 return !trailingComma;
const LangOptions & getLangOpts() const
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
ActionResult< Expr * > ExprResult
Parser - This implements a parser for the C family of languages.
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 ...
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
The message is a class message, and the identifier is a type name.
One of these records is kept for each identifier that is lexed.
const LangOptions & getLangOpts() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation Loc, bool GNUSyntax, ExprResult Init)
tok::TokenKind getKind() const
bool isArrayDesignator() const
StringRef getName() const
Return the actual identifier string.
The message is an instance message.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
bool isNot(tok::TokenKind K) const
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
const IdentifierInfo * getField() const
The result type of a method or function.
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion...
Stop skipping at semicolon.
Encodes a location in the source.
Scope * getCurScope() const
bool isArrayRangeDesignator() const
const Designator & getDesignator(unsigned Idx) const
The message is sent to 'super'.
ExprResult ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, SourceLocation RBraceLoc)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
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)) {...
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, Designation &Desig)
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
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.
ExprResult ParseConstantExpression(TypeCastState isTypeCast=NotTypeCast)
void AddDesignator(Designator D)
AddDesignator - Add a designator to the end of this list.
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, 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...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
Represents a complete lambda introducer.
Designation - Represent a full designation, which is a sequence of designators.
static Designator getArray(Expr *Index, SourceLocation LBracketLoc)
A trivial tuple used to represent a source range.
static Designator getArrayRange(Expr *Start, Expr *End, SourceLocation LBracketLoc, SourceLocation EllipsisLoc)
unsigned getNumDesignators() const
static OpaquePtr getFromOpaquePtr(void *P)
SourceLocation ColonLoc
Location of ':'.
Stop skipping at specified token, but don't skip the token itself.
IdentifierInfo * getIdentifierInfo() const