blob: 9008f3ece56563c34d1379976335bb2c5719cbba [file] [log] [blame]
Chris Lattner0ccd51e2006-08-09 05:47:47 +00001//===--- Statement.cpp - Statement and Block Parser -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Statement and Block portions of the Parser
11// interface.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Parse/Parser.h"
16#include "clang/Basic/Diagnostic.h"
17using namespace llvm;
18using namespace clang;
19
20//===----------------------------------------------------------------------===//
21// C99 6.8: Statements and Blocks.
22//===----------------------------------------------------------------------===//
23
24/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
25/// StatementOrDeclaration:
26/// statement
27/// declaration
28///
29/// statement:
30/// labeled-statement
31/// compound-statement
32/// expression-statement
33/// selection-statement
34/// iteration-statement
35/// jump-statement
36/// [OBC] objc-throw-statement [TODO]
37/// [OBC] objc-try-catch-statement [TODO]
38/// [OBC] objc-synchronized-statement [TODO]
39/// [GNU] asm-statement [TODO]
40/// [OMP] openmp-construct [TODO]
41///
42/// labeled-statement:
43/// identifier ':' statement
44/// 'case' constant-expression ':' statement
45/// 'default' ':' statement
46///
47/// expression-statement:
48/// expression[opt] ';'
49///
50/// selection-statement:
51/// if-statement
52/// switch-statement
53///
54/// iteration-statement:
55/// while-statement
56/// do-statement
57/// for-statement
58///
59/// jump-statement:
60/// 'goto' identifier ';'
61/// 'continue' ';'
62/// 'break' ';'
63/// 'return' expression[opt] ';'
64/// [GNU] 'goto' '*' expression ';' [TODO]
65///
66/// [OBC] objc-throw-statement: [TODO]
67/// [OBC] '@' 'throw' expression ';' [TODO]
68/// [OBC] '@' 'throw' ';' [TODO]
69///
Chris Lattnerc951dae2006-08-10 04:23:57 +000070void Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
Chris Lattner0ccd51e2006-08-09 05:47:47 +000071 switch (Tok.getKind()) {
72 default:
73 Diag(Tok, diag::err_expected_statement_declaration);
74 SkipUntil(tok::semi);
75 break;
76
Chris Lattnerc951dae2006-08-10 04:23:57 +000077 // C99 6.8.2: compound-statement -> '{}' block
78 case tok::l_brace:
Chris Lattner0ccd51e2006-08-09 05:47:47 +000079 ParseCompoundStatement();
80 break;
Chris Lattnerc951dae2006-08-10 04:23:57 +000081 // C99 6.8.3: expression[opt] ';'
82 case tok::semi:
83 ConsumeToken();
84 break;
85
86 // C99 6.8.4.1: if-statement
87 case tok::kw_if:
88 ParseIfStatement();
89 break;
90
91
92 // TODO: Handle OnlyStatement..
Chris Lattner0ccd51e2006-08-09 05:47:47 +000093 }
94}
95
96/// ParseCompoundStatement - Parse a "{}" block.
97///
98/// compound-statement: [C99 6.8.2]
99/// { block-item-list[opt] }
100/// [GNU] { label-declarations block-item-list } [TODO]
101///
102/// block-item-list:
103/// block-item
104/// block-item-list block-item
105///
106/// block-item:
107/// declaration
108/// [GNU] '__extension__' declaration [TODO]
109/// statement
110/// [OMP] openmp-directive [TODO]
111///
112/// [GNU] label-declarations:
113/// [GNU] label-declaration
114/// [GNU] label-declarations label-declaration
115///
116/// [GNU] label-declaration:
117/// [GNU] '__label__' identifier-list ';'
118///
119/// [OMP] openmp-directive: [TODO]
120/// [OMP] barrier-directive
121/// [OMP] flush-directive
122void Parser::ParseCompoundStatement() {
123 assert(Tok.getKind() == tok::l_brace && "Not a compount stmt!");
124 ConsumeBrace(); // eat the '{'.
125
126 while (Tok.getKind() != tok::r_brace && Tok.getKind() != tok::eof)
Chris Lattnerc951dae2006-08-10 04:23:57 +0000127 ParseStatementOrDeclaration(false);
Chris Lattner0ccd51e2006-08-09 05:47:47 +0000128
129 // We broke out of the while loop because we found a '}' or EOF.
130 if (Tok.getKind() == tok::r_brace)
131 ConsumeBrace();
132 else
133 Diag(Tok, diag::err_expected_rbrace);
134}
Chris Lattnerc951dae2006-08-10 04:23:57 +0000135
136/// ParseIfStatement
137/// if-statement: [C99 6.8.4.1]
138/// 'if' '(' expression ')' statement
139/// 'if' '(' expression ')' statement 'else' statement
140void Parser::ParseIfStatement() {
141 assert(Tok.getKind() == tok::kw_if && "Not an if stmt!");
142 ConsumeToken(); // eat the 'if'.
143
144 if (Tok.getKind() != tok::l_paren) {
145 Diag(Tok, diag::err_expected_lparen_after_if, "if");
146 SkipUntil(tok::semi);
147 return;
148 }
149
150 // Parse the condition.
151 ParseParenExpression();
152
153 // Read the if condition.
154 ParseStatement();
155
156 // If it has an else, parse it.
157 if (Tok.getKind() == tok::kw_else) {
158 ConsumeToken();
159 ParseStatement();
160 }
161
162}
163
164