clang  6.0.0svn
ParseInit.cpp
Go to the documentation of this file.
1 //===--- ParseInit.cpp - Initializer Parsing ------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements initializer parsing as specified by C99 6.7.8.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/Parse/Parser.h"
17 #include "clang/Sema/Designator.h"
18 #include "clang/Sema/Scope.h"
19 #include "llvm/ADT/SmallString.h"
20 using namespace clang;
21 
22 
23 /// MayBeDesignationStart - Return true if the current token might be the start
24 /// of a designator. If we can tell it is impossible that it is a designator,
25 /// return false.
26 bool Parser::MayBeDesignationStart() {
27  switch (Tok.getKind()) {
28  default:
29  return false;
30 
31  case tok::period: // designator: '.' identifier
32  return true;
33 
34  case tok::l_square: { // designator: array-designator
35  if (!PP.getLangOpts().CPlusPlus11)
36  return true;
37 
38  // C++11 lambda expressions and C99 designators can be ambiguous all the
39  // way through the closing ']' and to the next character. Handle the easy
40  // cases here, and fall back to tentative parsing if those fail.
41  switch (PP.LookAhead(0).getKind()) {
42  case tok::equal:
43  case tok::r_square:
44  // Definitely starts a lambda expression.
45  return false;
46 
47  case tok::amp:
48  case tok::kw_this:
49  case tok::identifier:
50  // We have to do additional analysis, because these could be the
51  // start of a constant expression or a lambda capture list.
52  break;
53 
54  default:
55  // Anything not mentioned above cannot occur following a '[' in a
56  // lambda expression.
57  return true;
58  }
59 
60  // Handle the complicated case below.
61  break;
62  }
63  case tok::identifier: // designation: identifier ':'
64  return PP.LookAhead(0).is(tok::colon);
65  }
66 
67  // Parse up to (at most) the token after the closing ']' to determine
68  // whether this is a C99 designator or a lambda.
69  TentativeParsingAction Tentative(*this);
70 
71  LambdaIntroducer Intro;
72  bool SkippedInits = false;
73  Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
74 
75  if (DiagID) {
76  // If this can't be a lambda capture list, it's a designator.
77  Tentative.Revert();
78  return true;
79  }
80 
81  // Once we hit the closing square bracket, we look at the next
82  // token. If it's an '=', this is a designator. Otherwise, it's a
83  // lambda expression. This decision favors lambdas over the older
84  // GNU designator syntax, which allows one to omit the '=', but is
85  // consistent with GCC.
86  tok::TokenKind Kind = Tok.getKind();
87  // FIXME: If we didn't skip any inits, parse the lambda from here
88  // rather than throwing away then reparsing the LambdaIntroducer.
89  Tentative.Revert();
90  return Kind == tok::equal;
91 }
92 
94  Designation &Desig) {
95  // If we have exactly one array designator, this used the GNU
96  // 'designation: array-designator' extension, otherwise there should be no
97  // designators at all!
98  if (Desig.getNumDesignators() == 1 &&
99  (Desig.getDesignator(0).isArrayDesignator() ||
101  P.Diag(Loc, diag::ext_gnu_missing_equal_designator);
102  else if (Desig.getNumDesignators() > 0)
103  P.Diag(Loc, diag::err_expected_equal_designator);
104 }
105 
106 /// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
107 /// checking to see if the token stream starts with a designator.
108 ///
109 /// designation:
110 /// designator-list '='
111 /// [GNU] array-designator
112 /// [GNU] identifier ':'
113 ///
114 /// designator-list:
115 /// designator
116 /// designator-list designator
117 ///
118 /// designator:
119 /// array-designator
120 /// '.' identifier
121 ///
122 /// array-designator:
123 /// '[' constant-expression ']'
124 /// [GNU] '[' constant-expression '...' constant-expression ']'
125 ///
126 /// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
127 /// initializer (because it is an expression). We need to consider this case
128 /// when parsing array designators.
129 ///
130 ExprResult Parser::ParseInitializerWithPotentialDesignator() {
131 
132  // If this is the old-style GNU extension:
133  // designation ::= identifier ':'
134  // Handle it as a field designator. Otherwise, this must be the start of a
135  // normal expression.
136  if (Tok.is(tok::identifier)) {
137  const IdentifierInfo *FieldName = Tok.getIdentifierInfo();
138 
139  SmallString<256> NewSyntax;
140  llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName()
141  << " = ";
142 
143  SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.
144 
145  assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
147 
148  Diag(NameLoc, diag::ext_gnu_old_style_field_designator)
149  << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc),
150  NewSyntax);
151 
152  Designation D;
153  D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
154  return Actions.ActOnDesignatedInitializer(D, ColonLoc, true,
155  ParseInitializer());
156  }
157 
158  // Desig - This is initialized when we see our first designator. We may have
159  // an objc message send with no designator, so we don't want to create this
160  // eagerly.
161  Designation Desig;
162 
163  // Parse each designator in the designator list until we find an initializer.
164  while (Tok.is(tok::period) || Tok.is(tok::l_square)) {
165  if (Tok.is(tok::period)) {
166  // designator: '.' identifier
167  SourceLocation DotLoc = ConsumeToken();
168 
169  if (Tok.isNot(tok::identifier)) {
170  Diag(Tok.getLocation(), diag::err_expected_field_designator);
171  return ExprError();
172  }
173 
175  Tok.getLocation()));
176  ConsumeToken(); // Eat the identifier.
177  continue;
178  }
179 
180  // We must have either an array designator now or an objc message send.
181  assert(Tok.is(tok::l_square) && "Unexpected token!");
182 
183  // Handle the two forms of array designator:
184  // array-designator: '[' constant-expression ']'
185  // array-designator: '[' constant-expression '...' constant-expression ']'
186  //
187  // Also, we have to handle the case where the expression after the
188  // designator an an objc message send: '[' objc-message-expr ']'.
189  // Interesting cases are:
190  // [foo bar] -> objc message send
191  // [foo] -> array designator
192  // [foo ... bar] -> array designator
193  // [4][foo bar] -> obsolete GNU designation with objc message send.
194  //
195  // We do not need to check for an expression starting with [[ here. If it
196  // contains an Objective-C message send, then it is not an ill-formed
197  // attribute. If it is a lambda-expression within an array-designator, then
198  // it will be rejected because a constant-expression cannot begin with a
199  // lambda-expression.
200  InMessageExpressionRAIIObject InMessage(*this, true);
201 
202  BalancedDelimiterTracker T(*this, tok::l_square);
203  T.consumeOpen();
204  SourceLocation StartLoc = T.getOpenLocation();
205 
206  ExprResult Idx;
207 
208  // If Objective-C is enabled and this is a typename (class message
209  // send) or send to 'super', parse this as a message send
210  // expression. We handle C++ and C separately, since C++ requires
211  // much more complicated parsing.
212  if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus) {
213  // Send to 'super'.
214  if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
215  NextToken().isNot(tok::period) &&
217  CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
218  return ParseAssignmentExprWithObjCMessageExprStart(
219  StartLoc, ConsumeToken(), nullptr, nullptr);
220  }
221 
222  // Parse the receiver, which is either a type or an expression.
223  bool IsExpr;
224  void *TypeOrExpr;
225  if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
226  SkipUntil(tok::r_square, StopAtSemi);
227  return ExprError();
228  }
229 
230  // If the receiver was a type, we have a class message; parse
231  // the rest of it.
232  if (!IsExpr) {
233  CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
234  return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
235  SourceLocation(),
236  ParsedType::getFromOpaquePtr(TypeOrExpr),
237  nullptr);
238  }
239 
240  // If the receiver was an expression, we still don't know
241  // whether we have a message send or an array designator; just
242  // adopt the expression for further analysis below.
243  // FIXME: potentially-potentially evaluated expression above?
244  Idx = ExprResult(static_cast<Expr*>(TypeOrExpr));
245  } else if (getLangOpts().ObjC1 && Tok.is(tok::identifier)) {
246  IdentifierInfo *II = Tok.getIdentifierInfo();
247  SourceLocation IILoc = Tok.getLocation();
248  ParsedType ReceiverType;
249  // Three cases. This is a message send to a type: [type foo]
250  // This is a message send to super: [super foo]
251  // This is a message sent to an expr: [super.bar foo]
252  switch (Actions.getObjCMessageKind(
253  getCurScope(), II, IILoc, II == Ident_super,
254  NextToken().is(tok::period), ReceiverType)) {
256  CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
257  return ParseAssignmentExprWithObjCMessageExprStart(
258  StartLoc, ConsumeToken(), nullptr, nullptr);
259 
261  CheckArrayDesignatorSyntax(*this, StartLoc, Desig);
262  ConsumeToken(); // the identifier
263  if (!ReceiverType) {
264  SkipUntil(tok::r_square, StopAtSemi);
265  return ExprError();
266  }
267 
268  // Parse type arguments and protocol qualifiers.
269  if (Tok.is(tok::less)) {
270  SourceLocation NewEndLoc;
271  TypeResult NewReceiverType
272  = parseObjCTypeArgsAndProtocolQualifiers(IILoc, ReceiverType,
273  /*consumeLastToken=*/true,
274  NewEndLoc);
275  if (!NewReceiverType.isUsable()) {
276  SkipUntil(tok::r_square, StopAtSemi);
277  return ExprError();
278  }
279 
280  ReceiverType = NewReceiverType.get();
281  }
282 
283  return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
284  SourceLocation(),
285  ReceiverType,
286  nullptr);
287 
289  // Fall through; we'll just parse the expression and
290  // (possibly) treat this like an Objective-C message send
291  // later.
292  break;
293  }
294  }
295 
296  // Parse the index expression, if we haven't already gotten one
297  // above (which can only happen in Objective-C++).
298  // Note that we parse this as an assignment expression, not a constant
299  // expression (allowing *=, =, etc) to handle the objc case. Sema needs
300  // to validate that the expression is a constant.
301  // FIXME: We also need to tell Sema that we're in a
302  // potentially-potentially evaluated context.
303  if (!Idx.get()) {
305  if (Idx.isInvalid()) {
306  SkipUntil(tok::r_square, StopAtSemi);
307  return Idx;
308  }
309  }
310 
311  // Given an expression, we could either have a designator (if the next
312  // tokens are '...' or ']' or an objc message send. If this is an objc
313  // message send, handle it now. An objc-message send is the start of
314  // an assignment-expression production.
315  if (getLangOpts().ObjC1 && Tok.isNot(tok::ellipsis) &&
316  Tok.isNot(tok::r_square)) {
317  CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig);
318  return ParseAssignmentExprWithObjCMessageExprStart(
319  StartLoc, SourceLocation(), nullptr, Idx.get());
320  }
321 
322  // If this is a normal array designator, remember it.
323  if (Tok.isNot(tok::ellipsis)) {
324  Desig.AddDesignator(Designator::getArray(Idx.get(), StartLoc));
325  } else {
326  // Handle the gnu array range extension.
327  Diag(Tok, diag::ext_gnu_array_range);
328  SourceLocation EllipsisLoc = ConsumeToken();
329 
331  if (RHS.isInvalid()) {
332  SkipUntil(tok::r_square, StopAtSemi);
333  return RHS;
334  }
336  RHS.get(),
337  StartLoc, EllipsisLoc));
338  }
339 
340  T.consumeClose();
341  Desig.getDesignator(Desig.getNumDesignators() - 1).setRBracketLoc(
342  T.getCloseLocation());
343  }
344 
345  // Okay, we're done with the designator sequence. We know that there must be
346  // at least one designator, because the only case we can get into this method
347  // without a designator is when we have an objc message send. That case is
348  // handled and returned from above.
349  assert(!Desig.empty() && "Designator is empty?");
350 
351  // Handle a normal designator sequence end, which is an equal.
352  if (Tok.is(tok::equal)) {
353  SourceLocation EqualLoc = ConsumeToken();
354  return Actions.ActOnDesignatedInitializer(Desig, EqualLoc, false,
355  ParseInitializer());
356  }
357 
358  // We read some number of designators and found something that isn't an = or
359  // an initializer. If we have exactly one array designator, this
360  // is the GNU 'designation: array-designator' extension. Otherwise, it is a
361  // parse error.
362  if (Desig.getNumDesignators() == 1 &&
363  (Desig.getDesignator(0).isArrayDesignator() ||
365  Diag(Tok, diag::ext_gnu_missing_equal_designator)
366  << FixItHint::CreateInsertion(Tok.getLocation(), "= ");
367  return Actions.ActOnDesignatedInitializer(Desig, Tok.getLocation(),
368  true, ParseInitializer());
369  }
370 
371  Diag(Tok, diag::err_expected_equal_designator);
372  return ExprError();
373 }
374 
375 
376 /// ParseBraceInitializer - Called when parsing an initializer that has a
377 /// leading open brace.
378 ///
379 /// initializer: [C99 6.7.8]
380 /// '{' initializer-list '}'
381 /// '{' initializer-list ',' '}'
382 /// [GNU] '{' '}'
383 ///
384 /// initializer-list:
385 /// designation[opt] initializer ...[opt]
386 /// initializer-list ',' designation[opt] initializer ...[opt]
387 ///
388 ExprResult Parser::ParseBraceInitializer() {
389  InMessageExpressionRAIIObject InMessage(*this, false);
390 
391  BalancedDelimiterTracker T(*this, tok::l_brace);
392  T.consumeOpen();
393  SourceLocation LBraceLoc = T.getOpenLocation();
394 
395  /// InitExprs - This is the actual list of expressions contained in the
396  /// initializer.
397  ExprVector InitExprs;
398 
399  if (Tok.is(tok::r_brace)) {
400  // Empty initializers are a C++ feature and a GNU extension to C.
401  if (!getLangOpts().CPlusPlus)
402  Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
403  // Match the '}'.
404  return Actions.ActOnInitList(LBraceLoc, None, ConsumeBrace());
405  }
406 
407  // Enter an appropriate expression evaluation context for an initializer list.
410 
411  bool InitExprsOk = true;
412 
413  while (1) {
414  // Handle Microsoft __if_exists/if_not_exists if necessary.
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;
419  ConsumeToken();
420  }
421  if (Tok.is(tok::r_brace)) break;
422  continue;
423  }
424 
425  // Parse: designation[opt] initializer
426 
427  // If we know that this cannot be a designation, just parse the nested
428  // initializer directly.
429  ExprResult SubElt;
430  if (MayBeDesignationStart())
431  SubElt = ParseInitializerWithPotentialDesignator();
432  else
433  SubElt = ParseInitializer();
434 
435  if (Tok.is(tok::ellipsis))
436  SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
437 
438  SubElt = Actions.CorrectDelayedTyposInExpr(SubElt.get());
439 
440  // If we couldn't parse the subelement, bail out.
441  if (SubElt.isUsable()) {
442  InitExprs.push_back(SubElt.get());
443  } else {
444  InitExprsOk = false;
445 
446  // We have two ways to try to recover from this error: if the code looks
447  // grammatically ok (i.e. we have a comma coming up) try to continue
448  // parsing the rest of the initializer. This allows us to emit
449  // diagnostics for later elements that we find. If we don't see a comma,
450  // assume there is a parse error, and just skip to recover.
451  // FIXME: This comment doesn't sound right. If there is a r_brace
452  // immediately, it can't be an error, since there is no other way of
453  // leaving this loop except through this if.
454  if (Tok.isNot(tok::comma)) {
455  SkipUntil(tok::r_brace, StopBeforeMatch);
456  break;
457  }
458  }
459 
460  // If we don't have a comma continued list, we're done.
461  if (Tok.isNot(tok::comma)) break;
462 
463  // TODO: save comma locations if some client cares.
464  ConsumeToken();
465 
466  // Handle trailing comma.
467  if (Tok.is(tok::r_brace)) break;
468  }
469 
470  bool closed = !T.consumeClose();
471 
472  if (InitExprsOk && closed)
473  return Actions.ActOnInitList(LBraceLoc, InitExprs,
474  T.getCloseLocation());
475 
476  return ExprError(); // an error occurred.
477 }
478 
479 
480 // Return true if a comma (or closing brace) is necessary after the
481 // __if_exists/if_not_exists statement.
482 bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
483  bool &InitExprsOk) {
484  bool trailingComma = false;
485  IfExistsCondition Result;
486  if (ParseMicrosoftIfExistsCondition(Result))
487  return false;
488 
489  BalancedDelimiterTracker Braces(*this, tok::l_brace);
490  if (Braces.consumeOpen()) {
491  Diag(Tok, diag::err_expected) << tok::l_brace;
492  return false;
493  }
494 
495  switch (Result.Behavior) {
496  case IEB_Parse:
497  // Parse the declarations below.
498  break;
499 
500  case IEB_Dependent:
501  Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
502  << Result.IsIfExists;
503  // Fall through to skip.
504  LLVM_FALLTHROUGH;
505 
506  case IEB_Skip:
507  Braces.skipToEnd();
508  return false;
509  }
510 
511  while (!isEofOrEom()) {
512  trailingComma = false;
513  // If we know that this cannot be a designation, just parse the nested
514  // initializer directly.
515  ExprResult SubElt;
516  if (MayBeDesignationStart())
517  SubElt = ParseInitializerWithPotentialDesignator();
518  else
519  SubElt = ParseInitializer();
520 
521  if (Tok.is(tok::ellipsis))
522  SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
523 
524  // If we couldn't parse the subelement, bail out.
525  if (!SubElt.isInvalid())
526  InitExprs.push_back(SubElt.get());
527  else
528  InitExprsOk = false;
529 
530  if (Tok.is(tok::comma)) {
531  ConsumeToken();
532  trailingComma = true;
533  }
534 
535  if (Tok.is(tok::r_brace))
536  break;
537  }
538 
539  Braces.consumeClose();
540 
541  return !trailingComma;
542 }
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)) {...
Definition: Token.h:95
ActionResult< Expr * > ExprResult
Definition: Ownership.h:251
StringRef P
SourceLocation getCloseLocation() const
const IdentifierInfo * getField() const
Definition: Designator.h:74
bool isArrayRangeDesignator() const
Definition: Designator.h:72
Parser - This implements a parser for the C family of languages.
Definition: Parser.h:57
RAII object that enters a new expression evaluation context.
Definition: Sema.h:10617
bool isInObjcMethodScope() const
isInObjcMethodScope - Return true if this scope is, or is contained in, an Objective-C method body...
Definition: Scope.h:345
tok::TokenKind getKind() const
Definition: Token.h:90
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 ...
Definition: Parser.h:939
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Definition: Parser.h:607
The message is a class message, and the identifier is a type name.
Definition: Sema.h:8101
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
Definition: Preprocessor.h:728
PtrTy get() const
Definition: Ownership.h:162
ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation Loc, bool GNUSyntax, ExprResult Init)
Definition: SemaInit.cpp:2809
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
Definition: Designator.h:193
const FunctionProtoType * T
The message is an instance message.
Definition: Sema.h:8098
bool isArrayDesignator() const
Definition: Designator.h:71
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Definition: Token.h:124
ObjCMessageKind getObjCMessageKind(Scope *S, IdentifierInfo *Name, SourceLocation NameLoc, bool IsSuper, bool HasTrailingDot, ParsedType &ReceiverType)
bool isInvalid() const
Definition: Ownership.h:158
SourceLocation getOpenLocation() const
bool empty() const
Definition: Designator.h:191
bool isUsable() const
Definition: Ownership.h:159
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
Definition: Parser.h:271
Kind
const Designator & getDesignator(unsigned Idx) const
Definition: Designator.h:194
Stop skipping at semicolon.
Definition: Parser.h:919
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Definition: Ownership.h:144
Encodes a location in the source.
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:177
The message is sent to &#39;super&#39;.
Definition: Sema.h:8096
ExprResult ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, SourceLocation RBraceLoc)
Definition: SemaExpr.cpp:5690
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
Definition: TokenKinds.h:25
Scope * getCurScope() const
Definition: Parser.h:278
StringRef getName() const
Return the actual identifier string.
bool isNot(tok::TokenKind K) const
Definition: Token.h:96
Dataflow Directional Tag Classes.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Definition: Parser.cpp:72
static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, Designation &Desig)
Definition: ParseInit.cpp:93
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn&#39;t include (top-level) commas.
Definition: ParseExpr.cpp:156
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.
Definition: Diagnostic.h:90
ExprResult ParseConstantExpression(TypeCastState isTypeCast=NotTypeCast)
Definition: ParseExpr.cpp:206
void AddDesignator(Designator D)
AddDesignator - Add a designator to the end of this list.
Definition: Designator.h:187
SourceLocation ConsumeToken()
ConsumeToken - Consume the current &#39;peek token&#39; and lex the next one.
Definition: Parser.h:316
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
Definition: Diagnostic.h:127
Represents a complete lambda introducer.
Definition: DeclSpec.h:2522
ExprResult ExprError()
Definition: Ownership.h:267
Designation - Represent a full designation, which is a sequence of designators.
Definition: Designator.h:181
static Designator getArray(Expr *Index, SourceLocation LBracketLoc)
Definition: Designator.h:136
A trivial tuple used to represent a source range.
static Designator getArrayRange(Expr *Start, Expr *End, SourceLocation LBracketLoc, SourceLocation EllipsisLoc)
Definition: Designator.h:146
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:85
SourceLocation ColonLoc
Location of &#39;:&#39;.
Definition: OpenMPClause.h:90
Stop skipping at specified token, but don&#39;t skip the token itself.
Definition: Parser.h:921