]> granicus.if.org Git - clang/blob - include/clang/Parse/Parser.h
68c7457a51a85ca2c5bfd0491b3b1b1cf4fb2605
[clang] / include / clang / Parse / Parser.h
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
20 namespace clang {
21   class DeclSpec;
22   class ObjCDeclSpec;
23   class Declarator;
24   class AttributeList;
25   class Scope;
26
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
29 /// been read.
30 ///
31 class Parser {
32   Preprocessor &PP;
33   
34   /// Tok - The current token we are peeking head.  All parsing methods assume
35   /// that this is valid.
36   Token Tok;
37   
38   unsigned short ParenCount, BracketCount, BraceCount;
39
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.
43   Action &Actions;
44   
45   Scope *CurScope;
46   Diagnostic &Diags;
47   
48   /// ScopeCache - Cache scopes to reduce malloc traffic.
49   enum { ScopeCacheSize = 16 };
50   unsigned NumCachedScopes;
51   Scope *ScopeCache[ScopeCacheSize];
52 public:
53   Parser(Preprocessor &PP, Action &Actions);
54   ~Parser();
55
56   const LangOptions &getLang() const { return PP.getLangOptions(); }
57   TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
58   Action &getActions() const { return Actions; }
59   
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;
66   
67   // Parsing methods.
68   
69   /// ParseTranslationUnit - All in one method that initializes parses, and
70   /// shuts down the parser.
71   void ParseTranslationUnit();
72   
73   /// Initialize - Warm up the parser.
74   ///
75   void Initialize();
76   
77   /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if 
78   /// the EOF was encountered.
79   bool ParseTopLevelDecl(DeclTy*& Result);
80   
81   /// Finalize - Shut down the parser.
82   ///
83   void Finalize();
84   
85 private:
86   //===--------------------------------------------------------------------===//
87   // Low-Level token peeking and consumption methods.
88   //
89   
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;
93   }
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;
97   }
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;
101   }
102   
103   /// isTokenStringLiteral - True if this token is a string-literal.
104   ///
105   bool isTokenStringLiteral() const {
106     return Tok.getKind() == tok::string_literal ||
107            Tok.getKind() == tok::wide_string_literal;
108   }
109   
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() &&
116            !isTokenBrace() &&
117            "Should consume special tokens with Consume*Token");
118     SourceLocation L = Tok.getLocation();
119     PP.Lex(Tok);
120     return L;
121   }
122   
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() {
127     if (isTokenParen())
128       return ConsumeParen();
129     else if (isTokenBracket())
130       return ConsumeBracket();
131     else if (isTokenBrace())
132       return ConsumeBrace();
133     else if (isTokenStringLiteral())
134       return ConsumeStringToken();
135     else
136       return ConsumeToken();
137   }
138   
139   /// ConsumeParen - This consume method keeps the paren count up-to-date.
140   ///
141   SourceLocation ConsumeParen() {
142     assert(isTokenParen() && "wrong consume method");
143     if (Tok.getKind() == tok::l_paren)
144       ++ParenCount;
145     else if (ParenCount)
146       --ParenCount;       // Don't let unbalanced )'s drive the count negative.
147     SourceLocation L = Tok.getLocation();
148     PP.Lex(Tok);
149     return L;
150   }
151   
152   /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
153   ///
154   SourceLocation ConsumeBracket() {
155     assert(isTokenBracket() && "wrong consume method");
156     if (Tok.getKind() == tok::l_square)
157       ++BracketCount;
158     else if (BracketCount)
159       --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
160     
161     SourceLocation L = Tok.getLocation();
162     PP.Lex(Tok);
163     return L;
164   }
165       
166   /// ConsumeBrace - This consume method keeps the brace count up-to-date.
167   ///
168   SourceLocation ConsumeBrace() {
169     assert(isTokenBrace() && "wrong consume method");
170     if (Tok.getKind() == tok::l_brace)
171       ++BraceCount;
172     else if (BraceCount)
173       --BraceCount;     // Don't let unbalanced }'s drive the count negative.
174     
175     SourceLocation L = Tok.getLocation();
176     PP.Lex(Tok);
177     return L;
178   }
179   
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
183   /// phase #6.
184   SourceLocation ConsumeStringToken() {
185     assert(isTokenStringLiteral() &&
186            "Should only consume string literals with this method");
187     SourceLocation L = Tok.getLocation();
188     PP.Lex(Tok);
189     return L;
190   }
191   
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);
200   
201   /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
202   /// input.  If so, it is consumed and false is returned.
203   ///
204   /// If the input is malformed, this emits the specified diagnostic.  Next, if
205   /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
206   /// returned.
207   bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
208                         const char *DiagMsg = "",
209                         tok::TokenKind SkipToTok = tok::unknown);
210
211   //===--------------------------------------------------------------------===//
212   // Scope manipulation
213   
214   /// EnterScope - Start a new scope.
215   void EnterScope(unsigned ScopeFlags);
216   
217   /// ExitScope - Pop a scope off the scope stack.
218   void ExitScope();
219
220   //===--------------------------------------------------------------------===//
221   // Diagnostic Emission and Error recovery.
222     
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);
228   }
229   
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 ';'
234   /// character.
235   /// 
236   /// If SkipUntil finds the specified token, it returns true, otherwise it
237   /// returns false.  
238   bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
239                  bool DontConsume = false) {
240     return SkipUntil(&T, 1, StopAtSemi, DontConsume);
241   }
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);
246   }
247   bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
248                  bool StopAtSemi = true, bool DontConsume = false);
249  
250   typedef Action::ExprResult ExprResult;
251   typedef Action::StmtResult StmtResult;
252     
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();
261
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);
274   
275   DeclTy *ObjCImpDecl;
276
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);
282   
283   IdentifierInfo *ParseObjCSelector(SourceLocation &MethodLocation);
284   // Definitions for Objective-c context sensitive keywords recognition.
285   enum ObjCTypeQual {
286     objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
287     objc_NumQuals
288   };
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
294   };
295   IdentifierInfo *ObjCPropertyAttrs[objc_NumAttrs];
296   bool isObjCPropertyAttribute();
297   
298   IdentifierInfo *ObjCForCollectionInKW;
299   bool isTokIdentifier_in() const;
300
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,
306                               DeclTy *classDecl,
307             tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
308   void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
309   DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc);
310   
311   DeclTy *ParseObjCMethodDefinition();
312   
313   //===--------------------------------------------------------------------===//
314   // C99 6.5: Expressions.
315
316   ExprResult ParseExpression();
317   ExprResult ParseConstantExpression();
318   ExprResult ParseAssignmentExpression();  // Expr that doesn't include commas.
319   
320   ExprResult ParseExpressionWithLeadingIdentifier(const Token &Tok);
321   ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
322   ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok);
323   ExprResult ParseAssignmentExpressionWithLeadingStar(const Token &Tok);
324
325   ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
326   ExprResult ParseCastExpression(bool isUnaryExpression);
327   ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
328   ExprResult ParseSizeofAlignofExpression();
329   ExprResult ParseBuiltinPrimaryExpression();
330   
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>
337   };
338   ExprResult ParseParenExpression(ParenParseOption &ExprType, TypeTy *&CastTy,
339                                   SourceLocation &RParenLoc);
340   
341   ExprResult ParseSimpleParenExpression() {  // Parse SimpleExpr only.
342     SourceLocation RParenLoc;
343     return ParseSimpleParenExpression(RParenLoc);
344   }
345   ExprResult ParseSimpleParenExpression(SourceLocation &RParenLoc) {
346     ParenParseOption Op = SimpleExpr;
347     TypeTy *CastTy;
348     return ParseParenExpression(Op, CastTy, RParenLoc);
349   }
350   ExprResult ParseStringLiteralExpression();
351   
352   //===--------------------------------------------------------------------===//
353   // C++ 5.2p1: C++ Casts
354   ExprResult ParseCXXCasts();
355
356   //===--------------------------------------------------------------------===//
357   // C++ 2.13.5: C++ Boolean Literals
358   ExprResult ParseCXXBoolLiteral();
359
360   //===--------------------------------------------------------------------===//
361   // C99 6.7.8: Initialization.
362   ExprResult ParseInitializer();
363   ExprResult ParseInitializerWithPotentialDesignator();
364   
365   //===--------------------------------------------------------------------===//
366   // Objective-C Expressions
367   
368   bool isTokObjCMessageIdentifierReceiver() const {
369     if (!Tok.is(tok::identifier))
370       return false;
371     
372     if (Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))
373       return true;
374     
375     return Tok.isNamedIdentifier("super");
376   }
377   
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);
387     
388   //===--------------------------------------------------------------------===//
389   // C99 6.8: Statements and Blocks.
390   
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);
416
417
418   //===--------------------------------------------------------------------===//
419   // C99 6.7: Declarations.
420   
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);
428   
429   void ParseObjCTypeQualifierList(ObjCDeclSpec &DS);
430
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,
436                             DeclTy *TagDecl);
437   void ParseStructDeclaration(DeclTy *TagDecl,
438                               llvm::SmallVectorImpl<DeclTy*> &FieldDecls);
439                               
440   bool isDeclarationSpecifier() const;
441   bool isTypeSpecifierQualifier() const;
442   bool isTypeQualifier() const;
443
444   TypeTy *ParseTypeName();
445   AttributeList *ParseAttributes();
446   void ParseTypeofSpecifier(DeclSpec &DS);
447   
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);
455   
456   //===--------------------------------------------------------------------===//
457   // C++ 7: Declarations [dcl.dcl]
458   
459   DeclTy *ParseNamespace(unsigned Context);
460   DeclTy *ParseLinkage(unsigned Context);
461
462 };
463
464 }  // end namespace clang
465
466 #endif