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