1 //===--- Parser.h - C Language Parser ---------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the Parser interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_PARSE_PARSER_H
15 #define LLVM_CLANG_PARSE_PARSER_H
17 #include "clang/Lex/Preprocessor.h"
18 #include "clang/Parse/Action.h"
27 /// Parser - This implements a parser for the C family of languages. After
28 /// parsing units of the grammar, productions are invoked to handle whatever has
34 /// Tok - The current token we are peeking head. All parsing methods assume
35 /// that this is valid.
38 unsigned short ParenCount, BracketCount, BraceCount;
40 /// Actions - These are the callbacks we invoke as we parse various constructs
41 /// in the file. This refers to the common base class between MinimalActions
42 /// and SemaActions for those uses that don't matter.
48 /// ScopeCache - Cache scopes to reduce malloc traffic.
49 enum { ScopeCacheSize = 16 };
50 unsigned NumCachedScopes;
51 Scope *ScopeCache[ScopeCacheSize];
53 Parser(Preprocessor &PP, Action &Actions);
56 const LangOptions &getLang() const { return PP.getLangOptions(); }
57 TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
58 Action &getActions() const { return Actions; }
60 // Type forwarding. All of these are statically 'void*', but they may all be
61 // different actual classes based on the actions in place.
62 typedef Action::ExprTy ExprTy;
63 typedef Action::StmtTy StmtTy;
64 typedef Action::DeclTy DeclTy;
65 typedef Action::TypeTy TypeTy;
69 /// ParseTranslationUnit - All in one method that initializes parses, and
70 /// shuts down the parser.
71 void ParseTranslationUnit();
73 /// Initialize - Warm up the parser.
77 /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
78 /// the EOF was encountered.
79 bool ParseTopLevelDecl(DeclTy*& Result);
81 /// Finalize - Shut down the parser.
86 //===--------------------------------------------------------------------===//
87 // Low-Level token peeking and consumption methods.
90 /// isTokenParen - Return true if the cur token is '(' or ')'.
91 bool isTokenParen() const {
92 return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
94 /// isTokenBracket - Return true if the cur token is '[' or ']'.
95 bool isTokenBracket() const {
96 return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
98 /// isTokenBrace - Return true if the cur token is '{' or '}'.
99 bool isTokenBrace() const {
100 return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
103 /// isTokenStringLiteral - True if this token is a string-literal.
105 bool isTokenStringLiteral() const {
106 return Tok.getKind() == tok::string_literal ||
107 Tok.getKind() == tok::wide_string_literal;
110 /// ConsumeToken - Consume the current 'peek token' and lex the next one.
111 /// This does not work will all kinds of tokens: strings and specific other
112 /// tokens must be consumed with custom methods below. This returns the
113 /// location of the consumed token.
114 SourceLocation ConsumeToken() {
115 assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
117 "Should consume special tokens with Consume*Token");
118 SourceLocation L = Tok.getLocation();
123 /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
124 /// current token type. This should only be used in cases where the type of
125 /// the token really isn't known, e.g. in error recovery.
126 SourceLocation ConsumeAnyToken() {
128 return ConsumeParen();
129 else if (isTokenBracket())
130 return ConsumeBracket();
131 else if (isTokenBrace())
132 return ConsumeBrace();
133 else if (isTokenStringLiteral())
134 return ConsumeStringToken();
136 return ConsumeToken();
139 /// ConsumeParen - This consume method keeps the paren count up-to-date.
141 SourceLocation ConsumeParen() {
142 assert(isTokenParen() && "wrong consume method");
143 if (Tok.getKind() == tok::l_paren)
146 --ParenCount; // Don't let unbalanced )'s drive the count negative.
147 SourceLocation L = Tok.getLocation();
152 /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
154 SourceLocation ConsumeBracket() {
155 assert(isTokenBracket() && "wrong consume method");
156 if (Tok.getKind() == tok::l_square)
158 else if (BracketCount)
159 --BracketCount; // Don't let unbalanced ]'s drive the count negative.
161 SourceLocation L = Tok.getLocation();
166 /// ConsumeBrace - This consume method keeps the brace count up-to-date.
168 SourceLocation ConsumeBrace() {
169 assert(isTokenBrace() && "wrong consume method");
170 if (Tok.getKind() == tok::l_brace)
173 --BraceCount; // Don't let unbalanced }'s drive the count negative.
175 SourceLocation L = Tok.getLocation();
180 /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
181 /// and returning the token kind. This method is specific to strings, as it
182 /// handles string literal concatenation, as per C99 5.1.1.2, translation
184 SourceLocation ConsumeStringToken() {
185 assert(isTokenStringLiteral() &&
186 "Should only consume string literals with this method");
187 SourceLocation L = Tok.getLocation();
192 /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
193 /// this helper function matches and consumes the specified RHS token if
194 /// present. If not present, it emits the specified diagnostic indicating
195 /// that the parser failed to match the RHS of the token at LHSLoc. LHSName
196 /// should be the name of the unmatched LHS token. This returns the location
197 /// of the consumed token.
198 SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
199 SourceLocation LHSLoc);
201 /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
202 /// input. If so, it is consumed and false is returned.
204 /// If the input is malformed, this emits the specified diagnostic. Next, if
205 /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
207 bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
208 const char *DiagMsg = "",
209 tok::TokenKind SkipToTok = tok::unknown);
211 //===--------------------------------------------------------------------===//
212 // Scope manipulation
214 /// EnterScope - Start a new scope.
215 void EnterScope(unsigned ScopeFlags);
217 /// ExitScope - Pop a scope off the scope stack.
220 //===--------------------------------------------------------------------===//
221 // Diagnostic Emission and Error recovery.
223 void Diag(SourceLocation Loc, unsigned DiagID,
224 const std::string &Msg = std::string());
225 void Diag(const Token &Tok, unsigned DiagID,
226 const std::string &M = std::string()) {
227 Diag(Tok.getLocation(), DiagID, M);
230 /// SkipUntil - Read tokens until we get to the specified token, then consume
231 /// it (unless DontConsume is true). Because we cannot guarantee that the
232 /// token will ever occur, this skips to the next token, or to some likely
233 /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
236 /// If SkipUntil finds the specified token, it returns true, otherwise it
238 bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
239 bool DontConsume = false) {
240 return SkipUntil(&T, 1, StopAtSemi, DontConsume);
242 bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
243 bool DontConsume = false) {
244 tok::TokenKind TokArray[] = {T1, T2};
245 return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
247 bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
248 bool StopAtSemi = true, bool DontConsume = false);
250 typedef Action::ExprResult ExprResult;
251 typedef Action::StmtResult StmtResult;
253 //===--------------------------------------------------------------------===//
254 // C99 6.9: External Definitions.
255 DeclTy *ParseExternalDeclaration();
256 DeclTy *ParseDeclarationOrFunctionDefinition();
257 DeclTy *ParseFunctionDefinition(Declarator &D);
258 void ParseKNRParamDeclarations(Declarator &D);
259 ExprResult ParseSimpleAsm();
260 ExprResult ParseAsmStringLiteral();
262 // Objective-C External Declarations
263 DeclTy *ParseObjCAtDirectives();
264 DeclTy *ParseObjCAtClassDeclaration(SourceLocation atLoc);
265 DeclTy *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
266 AttributeList *prefixAttrs = 0);
267 void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
268 SourceLocation atLoc);
269 bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<IdentifierInfo*> &,
270 SourceLocation &endProtoLoc);
271 void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
272 tok::ObjCKeywordKind contextKey);
273 DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
277 DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
278 DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
279 DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
280 DeclTy *ParseObjCPropertySynthesize(SourceLocation atLoc);
281 DeclTy *ParseObjCPropertyDynamic(SourceLocation atLoc);
283 IdentifierInfo *ParseObjCSelector(SourceLocation &MethodLocation);
284 // Definitions for Objective-c context sensitive keywords recognition.
286 objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
289 IdentifierInfo *ObjCTypeQuals[objc_NumQuals];
290 // Definitions for ObjC2's @property attributes.
291 enum ObjCPropertyAttr {
292 objc_readonly=0, objc_getter, objc_setter, objc_assign,
293 objc_readwrite, objc_retain, objc_copy, objc_nonatomic, objc_NumAttrs
295 IdentifierInfo *ObjCPropertyAttrs[objc_NumAttrs];
296 bool isObjCPropertyAttribute();
298 IdentifierInfo *ObjCForCollectionInKW;
299 bool isTokIdentifier_in() const;
301 TypeTy *ParseObjCTypeName(ObjCDeclSpec &DS);
302 void ParseObjCMethodRequirement();
303 DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat,
304 tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
305 DeclTy *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
307 tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
308 void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
309 DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc);
311 DeclTy *ParseObjCMethodDefinition();
313 //===--------------------------------------------------------------------===//
314 // C99 6.5: Expressions.
316 ExprResult ParseExpression();
317 ExprResult ParseConstantExpression();
318 ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
320 ExprResult ParseExpressionWithLeadingIdentifier(const Token &Tok);
321 ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
322 ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok);
323 ExprResult ParseAssignmentExpressionWithLeadingStar(const Token &Tok);
325 ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
326 ExprResult ParseCastExpression(bool isUnaryExpression);
327 ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
328 ExprResult ParseSizeofAlignofExpression();
329 ExprResult ParseBuiltinPrimaryExpression();
331 /// ParenParseOption - Control what ParseParenExpression will parse.
332 enum ParenParseOption {
333 SimpleExpr, // Only parse '(' expression ')'
334 CompoundStmt, // Also allow '(' compound-statement ')'
335 CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
336 CastExpr // Also allow '(' type-name ')' <anything>
338 ExprResult ParseParenExpression(ParenParseOption &ExprType, TypeTy *&CastTy,
339 SourceLocation &RParenLoc);
341 ExprResult ParseSimpleParenExpression() { // Parse SimpleExpr only.
342 SourceLocation RParenLoc;
343 return ParseSimpleParenExpression(RParenLoc);
345 ExprResult ParseSimpleParenExpression(SourceLocation &RParenLoc) {
346 ParenParseOption Op = SimpleExpr;
348 return ParseParenExpression(Op, CastTy, RParenLoc);
350 ExprResult ParseStringLiteralExpression();
352 //===--------------------------------------------------------------------===//
353 // C++ 5.2p1: C++ Casts
354 ExprResult ParseCXXCasts();
356 //===--------------------------------------------------------------------===//
357 // C++ 2.13.5: C++ Boolean Literals
358 ExprResult ParseCXXBoolLiteral();
360 //===--------------------------------------------------------------------===//
361 // C99 6.7.8: Initialization.
362 ExprResult ParseInitializer();
363 ExprResult ParseInitializerWithPotentialDesignator();
365 //===--------------------------------------------------------------------===//
366 // Objective-C Expressions
368 bool isTokObjCMessageIdentifierReceiver() const {
369 if (!Tok.is(tok::identifier))
372 if (Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))
375 return Tok.isNamedIdentifier("super");
378 ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
379 ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
380 ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
381 ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
382 ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
383 ExprResult ParseObjCMessageExpression();
384 ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
385 IdentifierInfo *ReceiverName,
386 ExprTy *ReceiverExpr);
388 //===--------------------------------------------------------------------===//
389 // C99 6.8: Statements and Blocks.
391 StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
392 StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
393 StmtResult ParseIdentifierStatement(bool OnlyStatement);
394 StmtResult ParseCaseStatement();
395 StmtResult ParseDefaultStatement();
396 StmtResult ParseCompoundStatement(bool isStmtExpr = false);
397 StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
398 StmtResult ParseIfStatement();
399 StmtResult ParseSwitchStatement();
400 StmtResult ParseWhileStatement();
401 StmtResult ParseDoStatement();
402 StmtResult ParseForStatement();
403 StmtResult ParseGotoStatement();
404 StmtResult ParseContinueStatement();
405 StmtResult ParseBreakStatement();
406 StmtResult ParseReturnStatement();
407 StmtResult ParseAsmStatement(bool &msAsm);
408 StmtResult FuzzyParseMicrosoftAsmStatement();
409 StmtResult ParseObjCAtStatement(SourceLocation atLoc);
410 StmtResult ParseObjCTryStmt(SourceLocation atLoc, bool &processAtKeyword);
411 StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
412 StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
413 bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
414 llvm::SmallVectorImpl<ExprTy*> &Constraints,
415 llvm::SmallVectorImpl<ExprTy*> &Exprs);
418 //===--------------------------------------------------------------------===//
419 // C99 6.7: Declarations.
421 DeclTy *ParseDeclaration(unsigned Context);
422 DeclTy *ParseSimpleDeclaration(unsigned Context);
423 DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
424 DeclTy *ParseFunctionStatementBody(DeclTy *Decl,
425 SourceLocation L, SourceLocation R);
426 void ParseDeclarationSpecifiers(DeclSpec &DS);
427 void ParseSpecifierQualifierList(DeclSpec &DS);
429 void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
431 bool ParseTag(DeclTy *&Decl, unsigned TagType, SourceLocation StartLoc);
432 void ParseEnumSpecifier(DeclSpec &DS);
433 void ParseEnumBody(SourceLocation StartLoc, DeclTy *TagDecl);
434 void ParseStructUnionSpecifier(DeclSpec &DS);
435 void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
437 void ParseStructDeclaration(DeclTy *TagDecl,
438 llvm::SmallVectorImpl<DeclTy*> &FieldDecls);
440 bool isDeclarationSpecifier() const;
441 bool isTypeSpecifierQualifier() const;
442 bool isTypeQualifier() const;
444 TypeTy *ParseTypeName();
445 AttributeList *ParseAttributes();
446 void ParseTypeofSpecifier(DeclSpec &DS);
448 /// ParseDeclarator - Parse and verify a newly-initialized declarator.
449 void ParseDeclarator(Declarator &D);
450 void ParseDeclaratorInternal(Declarator &D);
451 void ParseTypeQualifierListOpt(DeclSpec &DS);
452 void ParseDirectDeclarator(Declarator &D);
453 void ParseParenDeclarator(Declarator &D);
454 void ParseBracketDeclarator(Declarator &D);
456 //===--------------------------------------------------------------------===//
457 // C++ 7: Declarations [dcl.dcl]
459 DeclTy *ParseNamespace(unsigned Context);
460 DeclTy *ParseLinkage(unsigned Context);
464 } // end namespace clang