Parser.h revision fcdd8fe26de3eee44927600bf1853e21bd90dd84
1//===--- Parser.h - C Language Parser ---------------------------*- C++ -*-===//
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 defines the Parser interface.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_PARSE_PARSER_H
15#define LLVM_CLANG_PARSE_PARSER_H
16
17#include "clang/Lex/Preprocessor.h"
18#include "clang/Parse/Action.h"
19#include <stack>
20
21namespace clang {
22  class AttributeList;
23  class DeclSpec;
24  class Declarator;
25  class FieldDeclarator;
26  class ObjCDeclSpec;
27  class PragmaHandler;
28  class Scope;
29
30/// Parser - This implements a parser for the C family of languages.  After
31/// parsing units of the grammar, productions are invoked to handle whatever has
32/// been read.
33///
34class Parser {
35  Preprocessor &PP;
36
37  /// Tok - The current token we are peeking ahead.  All parsing methods assume
38  /// that this is valid.
39  Token Tok;
40
41  unsigned short ParenCount, BracketCount, BraceCount;
42
43  /// Actions - These are the callbacks we invoke as we parse various constructs
44  /// in the file.  This refers to the common base class between MinimalActions
45  /// and SemaActions for those uses that don't matter.
46  Action &Actions;
47
48  Scope *CurScope;
49  Diagnostic &Diags;
50
51  /// ScopeCache - Cache scopes to reduce malloc traffic.
52  enum { ScopeCacheSize = 16 };
53  unsigned NumCachedScopes;
54  Scope *ScopeCache[ScopeCacheSize];
55
56  /// Ident_super - IdentifierInfo for "super", to support fast
57  /// comparison.
58  IdentifierInfo *Ident_super;
59
60  PragmaHandler *PackHandler;
61
62public:
63  Parser(Preprocessor &PP, Action &Actions);
64  ~Parser();
65
66  const LangOptions &getLang() const { return PP.getLangOptions(); }
67  TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
68  Action &getActions() const { return Actions; }
69
70  // Type forwarding.  All of these are statically 'void*', but they may all be
71  // different actual classes based on the actions in place.
72  typedef Action::ExprTy ExprTy;
73  typedef Action::StmtTy StmtTy;
74  typedef Action::DeclTy DeclTy;
75  typedef Action::TypeTy TypeTy;
76
77  // Parsing methods.
78
79  /// ParseTranslationUnit - All in one method that initializes parses, and
80  /// shuts down the parser.
81  void ParseTranslationUnit();
82
83  /// Initialize - Warm up the parser.
84  ///
85  void Initialize();
86
87  /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
88  /// the EOF was encountered.
89  bool ParseTopLevelDecl(DeclTy*& Result);
90
91private:
92  //===--------------------------------------------------------------------===//
93  // Low-Level token peeking and consumption methods.
94  //
95
96  /// isTokenParen - Return true if the cur token is '(' or ')'.
97  bool isTokenParen() const {
98    return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
99  }
100  /// isTokenBracket - Return true if the cur token is '[' or ']'.
101  bool isTokenBracket() const {
102    return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
103  }
104  /// isTokenBrace - Return true if the cur token is '{' or '}'.
105  bool isTokenBrace() const {
106    return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
107  }
108
109  /// isTokenStringLiteral - True if this token is a string-literal.
110  ///
111  bool isTokenStringLiteral() const {
112    return Tok.getKind() == tok::string_literal ||
113           Tok.getKind() == tok::wide_string_literal;
114  }
115
116  /// ConsumeToken - Consume the current 'peek token' and lex the next one.
117  /// This does not work with all kinds of tokens: strings and specific other
118  /// tokens must be consumed with custom methods below.  This returns the
119  /// location of the consumed token.
120  SourceLocation ConsumeToken() {
121    assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
122           !isTokenBrace() &&
123           "Should consume special tokens with Consume*Token");
124    SourceLocation L = Tok.getLocation();
125    PP.Lex(Tok);
126    return L;
127  }
128
129  /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
130  /// current token type.  This should only be used in cases where the type of
131  /// the token really isn't known, e.g. in error recovery.
132  SourceLocation ConsumeAnyToken() {
133    if (isTokenParen())
134      return ConsumeParen();
135    else if (isTokenBracket())
136      return ConsumeBracket();
137    else if (isTokenBrace())
138      return ConsumeBrace();
139    else if (isTokenStringLiteral())
140      return ConsumeStringToken();
141    else
142      return ConsumeToken();
143  }
144
145  /// ConsumeParen - This consume method keeps the paren count up-to-date.
146  ///
147  SourceLocation ConsumeParen() {
148    assert(isTokenParen() && "wrong consume method");
149    if (Tok.getKind() == tok::l_paren)
150      ++ParenCount;
151    else if (ParenCount)
152      --ParenCount;       // Don't let unbalanced )'s drive the count negative.
153    SourceLocation L = Tok.getLocation();
154    PP.Lex(Tok);
155    return L;
156  }
157
158  /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
159  ///
160  SourceLocation ConsumeBracket() {
161    assert(isTokenBracket() && "wrong consume method");
162    if (Tok.getKind() == tok::l_square)
163      ++BracketCount;
164    else if (BracketCount)
165      --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
166
167    SourceLocation L = Tok.getLocation();
168    PP.Lex(Tok);
169    return L;
170  }
171
172  /// ConsumeBrace - This consume method keeps the brace count up-to-date.
173  ///
174  SourceLocation ConsumeBrace() {
175    assert(isTokenBrace() && "wrong consume method");
176    if (Tok.getKind() == tok::l_brace)
177      ++BraceCount;
178    else if (BraceCount)
179      --BraceCount;     // Don't let unbalanced }'s drive the count negative.
180
181    SourceLocation L = Tok.getLocation();
182    PP.Lex(Tok);
183    return L;
184  }
185
186  /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
187  /// and returning the token kind.  This method is specific to strings, as it
188  /// handles string literal concatenation, as per C99 5.1.1.2, translation
189  /// phase #6.
190  SourceLocation ConsumeStringToken() {
191    assert(isTokenStringLiteral() &&
192           "Should only consume string literals with this method");
193    SourceLocation L = Tok.getLocation();
194    PP.Lex(Tok);
195    return L;
196  }
197
198  /// GetLookAheadToken - This peeks ahead N tokens and returns that token
199  /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
200  /// returns the token after Tok, etc.
201  ///
202  /// Note that this differs from the Preprocessor's LookAhead method, because
203  /// the Parser always has one token lexed that the preprocessor doesn't.
204  ///
205  const Token &GetLookAheadToken(unsigned N) {
206    if (N == 0 || Tok.is(tok::eof)) return Tok;
207    return PP.LookAhead(N-1);
208  }
209
210  /// NextToken - This peeks ahead one token and returns it without
211  /// consuming it.
212  const Token &NextToken() {
213    return PP.LookAhead(0);
214  }
215
216
217  /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
218  /// this helper function matches and consumes the specified RHS token if
219  /// present.  If not present, it emits the specified diagnostic indicating
220  /// that the parser failed to match the RHS of the token at LHSLoc.  LHSName
221  /// should be the name of the unmatched LHS token.  This returns the location
222  /// of the consumed token.
223  SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
224                                     SourceLocation LHSLoc);
225
226  /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
227  /// input.  If so, it is consumed and false is returned.
228  ///
229  /// If the input is malformed, this emits the specified diagnostic.  Next, if
230  /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
231  /// returned.
232  bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
233                        const char *DiagMsg = "",
234                        tok::TokenKind SkipToTok = tok::unknown);
235
236  //===--------------------------------------------------------------------===//
237  // Scope manipulation
238
239  /// EnterScope - Start a new scope.
240  void EnterScope(unsigned ScopeFlags);
241
242  /// ExitScope - Pop a scope off the scope stack.
243  void ExitScope();
244
245  //===--------------------------------------------------------------------===//
246  // Diagnostic Emission and Error recovery.
247
248  bool Diag(SourceLocation Loc, unsigned DiagID,
249            const std::string &Msg = std::string());
250  bool Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R);
251  bool Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg,
252            const SourceRange& R1);
253  bool Diag(const Token &Tok, unsigned DiagID,
254            const std::string &M = std::string()) {
255    return Diag(Tok.getLocation(), DiagID, M);
256  }
257
258  /// SkipUntil - Read tokens until we get to the specified token, then consume
259  /// it (unless DontConsume is true).  Because we cannot guarantee that the
260  /// token will ever occur, this skips to the next token, or to some likely
261  /// good stopping point.  If StopAtSemi is true, skipping will stop at a ';'
262  /// character.
263  ///
264  /// If SkipUntil finds the specified token, it returns true, otherwise it
265  /// returns false.
266  bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
267                 bool DontConsume = false) {
268    return SkipUntil(&T, 1, StopAtSemi, DontConsume);
269  }
270  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
271                 bool DontConsume = false) {
272    tok::TokenKind TokArray[] = {T1, T2};
273    return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
274  }
275  bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
276                 bool StopAtSemi = true, bool DontConsume = false);
277
278  typedef Action::ExprResult ExprResult;
279  typedef Action::StmtResult StmtResult;
280
281  //===--------------------------------------------------------------------===//
282  // Lexing and parsing of C++ inline methods.
283
284  typedef llvm::SmallVector<Token, 32> TokensTy;
285  struct LexedMethod {
286    Action::DeclTy *D;
287    TokensTy Toks;
288    explicit LexedMethod(Action::DeclTy *MD) : D(MD) {}
289  };
290
291  /// LexedMethodsForTopClass - During parsing of a top (non-nested) C++ class,
292  /// its inline method definitions and the inline method definitions of its
293  /// nested classes are lexed and stored here.
294  typedef std::stack<LexedMethod> LexedMethodsForTopClass;
295
296  /// TopClassStacks - This is initialized with one LexedMethodsForTopClass used
297  /// for lexing all top classes, until a local class in an inline method is
298  /// encountered, at which point a new LexedMethodsForTopClass is pushed here
299  /// and used until the parsing of that local class is finished.
300  std::stack<LexedMethodsForTopClass> TopClassStacks;
301
302  LexedMethodsForTopClass &getCurTopClassStack() {
303    assert(!TopClassStacks.empty() && "No lexed method stacks!");
304    return TopClassStacks.top();
305  }
306
307  void PushTopClassStack() {
308    TopClassStacks.push(LexedMethodsForTopClass());
309  }
310  void PopTopClassStack() { TopClassStacks.pop(); }
311
312  DeclTy *ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D);
313  void ParseLexedMethodDefs();
314  bool ConsumeAndStoreUntil(tok::TokenKind T, TokensTy &Toks);
315
316  //===--------------------------------------------------------------------===//
317  // C99 6.9: External Definitions.
318  DeclTy *ParseExternalDeclaration();
319  DeclTy *ParseDeclarationOrFunctionDefinition();
320  DeclTy *ParseFunctionDefinition(Declarator &D);
321  void ParseKNRParamDeclarations(Declarator &D);
322  ExprResult ParseSimpleAsm();
323  ExprResult ParseAsmStringLiteral();
324
325  // Objective-C External Declarations
326  DeclTy *ParseObjCAtDirectives();
327  DeclTy *ParseObjCAtClassDeclaration(SourceLocation atLoc);
328  DeclTy *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
329                                          AttributeList *prefixAttrs = 0);
330  void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
331                                       SourceLocation atLoc);
332  bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclTy*> &P,
333                                   bool WarnOnDeclarations,
334                                   SourceLocation &EndProtoLoc);
335  void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
336                                  tok::ObjCKeywordKind contextKey);
337  DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
338                                         AttributeList *prefixAttrs = 0);
339
340  DeclTy *ObjCImpDecl;
341
342  DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
343  DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
344  DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
345  DeclTy *ParseObjCPropertySynthesize(SourceLocation atLoc);
346  DeclTy *ParseObjCPropertyDynamic(SourceLocation atLoc);
347
348  IdentifierInfo *ParseObjCSelector(SourceLocation &MethodLocation);
349  // Definitions for Objective-c context sensitive keywords recognition.
350  enum ObjCTypeQual {
351    objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
352    objc_NumQuals
353  };
354  IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
355  // Definitions for ObjC2's @property attributes.
356  enum ObjCPropertyAttr {
357    objc_readonly=0, objc_getter, objc_setter, objc_assign,
358    objc_readwrite, objc_retain, objc_copy, objc_nonatomic, objc_NumAttrs
359  };
360  IdentifierInfo *ObjCPropertyAttrs[objc_NumAttrs];
361  bool isObjCPropertyAttribute();
362
363  bool isTokIdentifier_in() const;
364
365  TypeTy *ParseObjCTypeName(ObjCDeclSpec &DS);
366  void ParseObjCMethodRequirement();
367  DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat,
368            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
369  DeclTy *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
370                              DeclTy *classDecl,
371            tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
372  void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
373
374  DeclTy *ParseObjCMethodDefinition();
375
376  //===--------------------------------------------------------------------===//
377  // C99 6.5: Expressions.
378
379  ExprResult ParseExpression();
380  ExprResult ParseConstantExpression();
381  ExprResult ParseAssignmentExpression();  // Expr that doesn't include commas.
382
383  ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
384
385  ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
386  ExprResult ParseCastExpression(bool isUnaryExpression);
387  ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
388  ExprResult ParseSizeofAlignofExpression();
389  ExprResult ParseBuiltinPrimaryExpression();
390
391  typedef llvm::SmallVector<ExprTy*, 8> ExprListTy;
392  typedef llvm::SmallVector<SourceLocation, 8> CommaLocsTy;
393
394  /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
395  bool ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs);
396
397  /// ParenParseOption - Control what ParseParenExpression will parse.
398  enum ParenParseOption {
399    SimpleExpr,      // Only parse '(' expression ')'
400    CompoundStmt,    // Also allow '(' compound-statement ')'
401    CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
402    CastExpr         // Also allow '(' type-name ')' <anything>
403  };
404  ExprResult ParseParenExpression(ParenParseOption &ExprType, TypeTy *&CastTy,
405                                  SourceLocation &RParenLoc);
406
407  ExprResult ParseSimpleParenExpression() {  // Parse SimpleExpr only.
408    SourceLocation RParenLoc;
409    return ParseSimpleParenExpression(RParenLoc);
410  }
411  ExprResult ParseSimpleParenExpression(SourceLocation &RParenLoc) {
412    ParenParseOption Op = SimpleExpr;
413    TypeTy *CastTy;
414    return ParseParenExpression(Op, CastTy, RParenLoc);
415  }
416  ExprResult ParseStringLiteralExpression();
417
418  //===--------------------------------------------------------------------===//
419  // C++ 5.2p1: C++ Casts
420  ExprResult ParseCXXCasts();
421
422  //===--------------------------------------------------------------------===//
423  // C++ 9.3.2: C++ 'this' pointer
424  ExprResult ParseCXXThis();
425
426  //===--------------------------------------------------------------------===//
427  // C++ 15: C++ Throw Expression
428  ExprResult ParseThrowExpression();
429
430  //===--------------------------------------------------------------------===//
431  // C++ 2.13.5: C++ Boolean Literals
432  ExprResult ParseCXXBoolLiteral();
433
434  //===--------------------------------------------------------------------===//
435  // C++ 5.2.3: Explicit type conversion (functional notation)
436  ExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
437
438  /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
439  /// This should only be called when the current token is known to be part of
440  /// simple-type-specifier.
441  void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
442
443  //===--------------------------------------------------------------------===//
444  // C++ if/switch/while/for condition expression.
445  ExprResult ParseCXXCondition();
446
447  //===--------------------------------------------------------------------===//
448  // C99 6.7.8: Initialization.
449  ExprResult ParseInitializer();
450  ExprResult ParseInitializerWithPotentialDesignator();
451
452  //===--------------------------------------------------------------------===//
453  // clang Expressions
454
455  ExprResult ParseBlockLiteralExpression();  // ^{...}
456
457  //===--------------------------------------------------------------------===//
458  // Objective-C Expressions
459
460  bool isTokObjCMessageIdentifierReceiver() const {
461    if (!Tok.is(tok::identifier))
462      return false;
463
464    if (Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))
465      return true;
466
467    return Tok.getIdentifierInfo() == Ident_super;
468  }
469
470  ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
471  ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
472  ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
473  ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
474  ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
475  ExprResult ParseObjCMessageExpression();
476  ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
477                                            IdentifierInfo *ReceiverName,
478                                            ExprTy *ReceiverExpr);
479  ExprResult ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracloc,
480                                                         IdentifierInfo *ReceiverName,
481                                                         ExprTy *ReceiverExpr);
482
483  //===--------------------------------------------------------------------===//
484  // C99 6.8: Statements and Blocks.
485
486  StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
487  StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
488  StmtResult ParseLabeledStatement();
489  StmtResult ParseCaseStatement();
490  StmtResult ParseDefaultStatement();
491  StmtResult ParseCompoundStatement(bool isStmtExpr = false);
492  StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
493  StmtResult ParseIfStatement();
494  StmtResult ParseSwitchStatement();
495  StmtResult ParseWhileStatement();
496  StmtResult ParseDoStatement();
497  StmtResult ParseForStatement();
498  StmtResult ParseGotoStatement();
499  StmtResult ParseContinueStatement();
500  StmtResult ParseBreakStatement();
501  StmtResult ParseReturnStatement();
502  StmtResult ParseAsmStatement(bool &msAsm);
503  StmtResult FuzzyParseMicrosoftAsmStatement();
504  StmtResult ParseObjCAtStatement(SourceLocation atLoc);
505  StmtResult ParseObjCTryStmt(SourceLocation atLoc);
506  StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
507  StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
508  bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
509                           llvm::SmallVectorImpl<ExprTy*> &Constraints,
510                           llvm::SmallVectorImpl<ExprTy*> &Exprs);
511
512
513  //===--------------------------------------------------------------------===//
514  // C99 6.7: Declarations.
515
516  DeclTy *ParseDeclaration(unsigned Context);
517  DeclTy *ParseSimpleDeclaration(unsigned Context);
518  DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
519  DeclTy *ParseFunctionStatementBody(DeclTy *Decl,
520                                     SourceLocation L, SourceLocation R);
521  void ParseDeclarationSpecifiers(DeclSpec &DS);
522  void ParseSpecifierQualifierList(DeclSpec &DS);
523
524  void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
525
526  void ParseEnumSpecifier(DeclSpec &DS);
527  void ParseEnumBody(SourceLocation StartLoc, DeclTy *TagDecl);
528  void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
529                            DeclTy *TagDecl);
530  void ParseStructDeclaration(DeclSpec &DS,
531                              llvm::SmallVectorImpl<FieldDeclarator> &Fields);
532
533  bool isDeclarationSpecifier() const;
534  bool isTypeSpecifierQualifier() const;
535  bool isTypeQualifier() const;
536
537  TypeTy *ParseTypeName();
538  AttributeList *ParseAttributes();
539  void ParseTypeofSpecifier(DeclSpec &DS);
540
541  /// ParseDeclarator - Parse and verify a newly-initialized declarator.
542  void ParseDeclarator(Declarator &D);
543  void ParseDeclaratorInternal(Declarator &D);
544  void ParseTypeQualifierListOpt(DeclSpec &DS);
545  void ParseDirectDeclarator(Declarator &D);
546  void ParseParenDeclarator(Declarator &D);
547  void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D);
548  void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
549                                             Declarator &D);
550  void ParseBracketDeclarator(Declarator &D);
551
552  //===--------------------------------------------------------------------===//
553  // C++ 7: Declarations [dcl.dcl]
554
555  DeclTy *ParseNamespace(unsigned Context);
556  DeclTy *ParseLinkage(unsigned Context);
557
558  //===--------------------------------------------------------------------===//
559  // C++ 9: classes [class] and C structs/unions.
560  void ParseClassSpecifier(DeclSpec &DS);
561  void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
562                                   DeclTy *TagDecl);
563  DeclTy *ParseCXXClassMemberDeclaration(AccessSpecifier AS);
564
565  //===--------------------------------------------------------------------===//
566  // C++ 10: Derived classes [class.derived]
567  void ParseBaseClause(DeclTy *ClassDecl);
568  bool ParseBaseSpecifier(DeclTy *ClassDecl);
569  AccessSpecifier getAccessSpecifierIfPresent() const;
570};
571
572}  // end namespace clang
573
574#endif
575