19 #include "llvm/ADT/SmallString.h" 20 using namespace clang;
26 bool Parser::MayBeDesignationStart() {
69 TentativeParsingAction Tentative(*
this);
72 bool SkippedInits =
false;
90 return Kind == tok::equal;
101 P.
Diag(Loc, diag::ext_gnu_missing_equal_designator);
103 P.
Diag(Loc, diag::err_expected_equal_designator);
130 ExprResult Parser::ParseInitializerWithPotentialDesignator() {
136 if (Tok.
is(tok::identifier)) {
140 llvm::raw_svector_ostream(NewSyntax) <<
'.' << FieldName->
getName()
145 assert(Tok.
is(tok::colon) &&
"MayBeDesignationStart not working properly!");
148 Diag(NameLoc, diag::ext_gnu_old_style_field_designator)
164 while (Tok.
is(tok::period) || Tok.
is(tok::l_square)) {
165 if (Tok.
is(tok::period)) {
169 if (Tok.
isNot(tok::identifier)) {
181 assert(Tok.
is(tok::l_square) &&
"Unexpected token!");
218 return ParseAssignmentExprWithObjCMessageExprStart(
225 if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
234 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
244 Idx =
ExprResult(static_cast<Expr*>(TypeOrExpr));
254 NextToken().is(tok::period), ReceiverType)) {
257 return ParseAssignmentExprWithObjCMessageExprStart(
269 if (Tok.
is(tok::less)) {
272 = parseObjCTypeArgsAndProtocolQualifiers(IILoc, ReceiverType,
280 ReceiverType = NewReceiverType.
get();
283 return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
316 Tok.
isNot(tok::r_square)) {
318 return ParseAssignmentExprWithObjCMessageExprStart(
323 if (Tok.
isNot(tok::ellipsis)) {
327 Diag(Tok, diag::ext_gnu_array_range);
337 StartLoc, EllipsisLoc));
349 assert(!Desig.
empty() &&
"Designator is empty?");
352 if (Tok.
is(tok::equal)) {
365 Diag(Tok, diag::ext_gnu_missing_equal_designator)
368 true, ParseInitializer());
371 Diag(Tok, diag::err_expected_equal_designator);
397 ExprVector InitExprs;
399 if (Tok.
is(tok::r_brace)) {
402 Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
411 bool InitExprsOk =
true;
415 if (
getLangOpts().MicrosoftExt && (Tok.
is(tok::kw___if_exists) ||
416 Tok.
is(tok::kw___if_not_exists))) {
417 if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
418 if (Tok.
isNot(tok::comma))
break;
421 if (Tok.
is(tok::r_brace))
break;
430 if (MayBeDesignationStart())
431 SubElt = ParseInitializerWithPotentialDesignator();
433 SubElt = ParseInitializer();
435 if (Tok.
is(tok::ellipsis))
442 InitExprs.push_back(SubElt.
get());
454 if (Tok.
isNot(tok::comma)) {
461 if (Tok.
isNot(tok::comma))
break;
467 if (Tok.
is(tok::r_brace))
break;
472 if (InitExprsOk && closed)
482 bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
484 bool trailingComma =
false;
486 if (ParseMicrosoftIfExistsCondition(Result))
491 Diag(Tok, diag::err_expected) << tok::l_brace;
495 switch (Result.Behavior) {
501 Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
502 << Result.IsIfExists;
511 while (!isEofOrEom()) {
512 trailingComma =
false;
516 if (MayBeDesignationStart())
517 SubElt = ParseInitializerWithPotentialDesignator();
519 SubElt = ParseInitializer();
521 if (Tok.
is(tok::ellipsis))
526 InitExprs.push_back(SubElt.
get());
530 if (Tok.
is(tok::comma)) {
532 trailingComma =
true;
535 if (Tok.
is(tok::r_brace))
541 return !trailingComma;
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
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)) {...
ActionResult< Expr * > ExprResult
SourceLocation getCloseLocation() const
const IdentifierInfo * getField() const
bool isArrayRangeDesignator() const
Parser - This implements a parser for the C family of languages.
RAII object that enters a new expression evaluation context.
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body...
tok::TokenKind getKind() 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 ...
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.
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
const LangOptions & getLangOpts() const
ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation Loc, bool GNUSyntax, ExprResult Init)
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...
unsigned getNumDesignators() const
const FunctionProtoType * T
The message is an instance message.
bool isArrayDesignator() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
SourceLocation getOpenLocation() 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...
const LangOptions & getLangOpts() const
const Designator & getDesignator(unsigned Idx) const
Stop skipping at semicolon.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
IdentifierInfo * getIdentifierInfo() 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.
Scope * getCurScope() const
StringRef getName() const
Return the actual identifier string.
bool isNot(tok::TokenKind K) const
Dataflow Directional Tag Classes.
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.
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)
static OpaquePtr getFromOpaquePtr(void *P)
SourceLocation ColonLoc
Location of ':'.
Stop skipping at specified token, but don't skip the token itself.