blob: 7f9d471d890fd6e1e15244b6a3f651773b1ac00f [file] [log] [blame]
Chris Lattneraf8d5812006-11-10 05:07:45 +00001//===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===//
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 semantic analysis for statements.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
15#include "clang/AST/Stmt.h"
Steve Naroff8eeeb132007-05-08 21:09:37 +000016#include "clang/AST/Expr.h"
Chris Lattnereaafe1222006-11-10 05:17:58 +000017#include "clang/Parse/Scope.h"
18#include "clang/Basic/Diagnostic.h"
Steve Naroff6f49f5d2007-05-29 14:23:36 +000019#include "clang/Basic/LangOptions.h"
20#include "clang/Lex/IdentifierTable.h"
Chris Lattneraf8d5812006-11-10 05:07:45 +000021using namespace llvm;
22using namespace clang;
23
Chris Lattner0f203a72007-05-28 01:45:28 +000024Sema::StmtResult Sema::ParseNullStmt(SourceLocation SemiLoc) {
25 return new NullStmt(SemiLoc);
26}
27
Chris Lattneraf8d5812006-11-10 05:07:45 +000028
29Action::StmtResult
30Sema::ParseCompoundStmt(SourceLocation L, SourceLocation R,
31 StmtTy **Elts, unsigned NumElts) {
Chris Lattner3bbe7be2007-05-20 22:47:04 +000032 return new CompoundStmt((Stmt**)Elts, NumElts);
Chris Lattneraf8d5812006-11-10 05:07:45 +000033}
34
35Action::StmtResult
36Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
37 SourceLocation DotDotDotLoc, ExprTy *RHSVal,
38 SourceLocation ColonLoc, StmtTy *SubStmt) {
Steve Naroff8eeeb132007-05-08 21:09:37 +000039 assert((LHSVal != 0) && "missing expression in case statement");
40
Steve Naroff72cada02007-05-18 00:18:52 +000041 SourceLocation expLoc;
Steve Naroff8eeeb132007-05-08 21:09:37 +000042 // C99 6.8.4.2p3: The expression shall be an integer constant.
Steve Naroff72cada02007-05-18 00:18:52 +000043 if (!((Expr *)LHSVal)->isIntegerConstantExpr(expLoc))
Steve Naroff8eeeb132007-05-08 21:09:37 +000044 return Diag(CaseLoc, diag::err_case_label_not_integer_constant_expr);
45
Chris Lattneraf8d5812006-11-10 05:07:45 +000046 return new CaseStmt((Expr*)LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
47}
48
49Action::StmtResult
50Sema::ParseDefaultStmt(SourceLocation DefaultLoc,
51 SourceLocation ColonLoc, StmtTy *SubStmt) {
52 return new DefaultStmt((Stmt*)SubStmt);
53}
54
55Action::StmtResult
56Sema::ParseLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
57 SourceLocation ColonLoc, StmtTy *SubStmt) {
Chris Lattnere2473062007-05-28 06:28:18 +000058 // Look up the record for this label identifier.
59 LabelStmt *&LabelDecl = LabelMap[II];
60
61 // If not forward referenced or defined already, just create a new LabelStmt.
62 if (LabelDecl == 0)
63 return LabelDecl = new LabelStmt(IdentLoc, II, (Stmt*)SubStmt);
64
Chris Lattnereefa10e2007-05-28 06:56:27 +000065 assert(LabelDecl->getID() == II && "Label mismatch!");
Chris Lattnere2473062007-05-28 06:28:18 +000066
67 // Otherwise, this label was either forward reference or multiply defined. If
68 // multiply defined, reject it now.
69 if (LabelDecl->getSubStmt()) {
Chris Lattnereefa10e2007-05-28 06:56:27 +000070 Diag(IdentLoc, diag::err_redefinition_of_label, LabelDecl->getName());
Chris Lattnere2473062007-05-28 06:28:18 +000071 Diag(LabelDecl->getIdentLoc(), diag::err_previous_definition);
72 return (Stmt*)SubStmt;
73 }
74
75 // Otherwise, this label was forward declared, and we just found its real
76 // definition. Fill in the forward definition and return it.
77 LabelDecl->setIdentLoc(IdentLoc);
78 LabelDecl->setSubStmt((Stmt*)SubStmt);
79 return LabelDecl;
Chris Lattneraf8d5812006-11-10 05:07:45 +000080}
81
82Action::StmtResult
83Sema::ParseIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
84 StmtTy *ThenVal, SourceLocation ElseLoc,
85 StmtTy *ElseVal) {
Steve Naroff86272ea2007-05-29 02:14:17 +000086 Expr *condExpr = (Expr *)CondVal;
87 assert(condExpr && "ParseIfStmt(): missing expression");
88
89 QualType condType = condExpr->getType();
90 assert(!condType.isNull() && "ParseIfStmt(): missing expression type");
91
92 if (!condType->isScalarType()) // C99 6.8.4.1p1
93 return Diag(IfLoc, diag::err_typecheck_statement_requires_scalar,
94 condType.getAsString(), condExpr->getSourceRange());
95
96 return new IfStmt(condExpr, (Stmt*)ThenVal, (Stmt*)ElseVal);
Chris Lattneraf8d5812006-11-10 05:07:45 +000097}
Steve Naroff86272ea2007-05-29 02:14:17 +000098
Chris Lattneraf8d5812006-11-10 05:07:45 +000099Action::StmtResult
100Sema::ParseSwitchStmt(SourceLocation SwitchLoc, ExprTy *Cond, StmtTy *Body) {
101 return new SwitchStmt((Expr*)Cond, (Stmt*)Body);
102}
103
104Action::StmtResult
Steve Naroff86272ea2007-05-29 02:14:17 +0000105Sema::ParseWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, StmtTy *Body) {
106 Expr *condExpr = (Expr *)Cond;
107 assert(condExpr && "ParseWhileStmt(): missing expression");
108
109 QualType condType = condExpr->getType();
110 assert(!condType.isNull() && "ParseWhileStmt(): missing expression type");
111
112 if (!condType->isScalarType()) // C99 6.8.5p2
113 return Diag(WhileLoc, diag::err_typecheck_statement_requires_scalar,
114 condType.getAsString(), condExpr->getSourceRange());
115
116 return new WhileStmt(condExpr, (Stmt*)Body);
Chris Lattneraf8d5812006-11-10 05:07:45 +0000117}
118
119Action::StmtResult
120Sema::ParseDoStmt(SourceLocation DoLoc, StmtTy *Body,
121 SourceLocation WhileLoc, ExprTy *Cond) {
Steve Naroff86272ea2007-05-29 02:14:17 +0000122 Expr *condExpr = (Expr *)Cond;
123 assert(condExpr && "ParseDoStmt(): missing expression");
124
125 QualType condType = condExpr->getType();
126 assert(!condType.isNull() && "ParseDoStmt(): missing expression type");
127
128 if (!condType->isScalarType()) // C99 6.8.5p2
129 return Diag(DoLoc, diag::err_typecheck_statement_requires_scalar,
130 condType.getAsString(), condExpr->getSourceRange());
131
132 return new DoStmt((Stmt*)Body, condExpr);
Chris Lattneraf8d5812006-11-10 05:07:45 +0000133}
134
135Action::StmtResult
136Sema::ParseForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
137 StmtTy *First, ExprTy *Second, ExprTy *Third,
138 SourceLocation RParenLoc, StmtTy *Body) {
Steve Naroff86272ea2007-05-29 02:14:17 +0000139 if (First) {
140 // C99 6.8.5p3: FIXME. Need to hack Parser::ParseForStatement() and
141 // declaration support to create a DeclStmt node. Once this is done,
142 // we can test for DeclStmt vs. Expr (already a sub-class of Stmt).
143 }
144 if (Second) {
145 Expr *testExpr = (Expr *)Second;
146 QualType testType = testExpr->getType();
147 assert(!testType.isNull() && "ParseForStmt(): missing test expression type");
148
149 if (!testType->isScalarType()) // C99 6.8.5p2
150 return Diag(ForLoc, diag::err_typecheck_statement_requires_scalar,
151 testType.getAsString(), testExpr->getSourceRange());
152 }
Chris Lattneraf8d5812006-11-10 05:07:45 +0000153 return new ForStmt((Stmt*)First, (Expr*)Second, (Expr*)Third, (Stmt*)Body);
154}
155
156
157Action::StmtResult
158Sema::ParseGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
159 IdentifierInfo *LabelII) {
Chris Lattnere2473062007-05-28 06:28:18 +0000160 // Look up the record for this label identifier.
161 LabelStmt *&LabelDecl = LabelMap[LabelII];
162
163 // If we haven't seen this label yet, create a forward reference.
164 if (LabelDecl == 0)
165 LabelDecl = new LabelStmt(LabelLoc, LabelII, 0);
166
167 return new GotoStmt(LabelDecl);
Chris Lattneraf8d5812006-11-10 05:07:45 +0000168}
169Action::StmtResult
170Sema::ParseIndirectGotoStmt(SourceLocation GotoLoc,SourceLocation StarLoc,
171 ExprTy *DestExp) {
172 return new IndirectGotoStmt((Expr*)DestExp);
173}
174
175Action::StmtResult
Chris Lattnereaafe1222006-11-10 05:17:58 +0000176Sema::ParseContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
177 Scope *S = CurScope->getContinueParent();
178 if (!S) {
179 // C99 6.8.6.2p1: A break shall appear only in or as a loop body.
180 Diag(ContinueLoc, diag::err_continue_not_in_loop);
181 return true;
182 }
183
184 // FIXME: Remember that this continue goes with this loop.
Chris Lattneraf8d5812006-11-10 05:07:45 +0000185 return new ContinueStmt();
186}
187
188Action::StmtResult
Chris Lattnereaafe1222006-11-10 05:17:58 +0000189Sema::ParseBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
190 Scope *S = CurScope->getBreakParent();
191 if (!S) {
192 // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
193 Diag(BreakLoc, diag::err_break_not_in_loop_or_switch);
194 return true;
195 }
196
197 // FIXME: Remember that this break goes with this loop/switch.
Chris Lattneraf8d5812006-11-10 05:07:45 +0000198 return new BreakStmt();
199}
200
201
202Action::StmtResult
203Sema::ParseReturnStmt(SourceLocation ReturnLoc, ExprTy *RetValExp) {
Steve Naroff9358c712007-05-27 23:58:33 +0000204 QualType lhsType = CurFunctionDecl->getResultType();
205
Steve Naroff9358c712007-05-27 23:58:33 +0000206 if (lhsType->isVoidType()) {
Steve Naroff6f49f5d2007-05-29 14:23:36 +0000207 if (RetValExp) // C99 6.8.6.4p1 (ext_ since GCC warns)
208 Diag(ReturnLoc, diag::ext_return_has_expr,
209 CurFunctionDecl->getIdentifier()->getName(),
210 ((Expr *)RetValExp)->getSourceRange());
211 return new ReturnStmt((Expr*)RetValExp);
212 } else {
213 if (!RetValExp) {
214 const char *funcName = CurFunctionDecl->getIdentifier()->getName();
215 if (getLangOptions().C99) // C99 6.8.6.4p1 (ext_ since GCC warns)
216 Diag(ReturnLoc, diag::ext_return_missing_expr, funcName);
217 else // C90 6.6.6.4p4
218 Diag(ReturnLoc, diag::warn_return_missing_expr, funcName);
219 return new ReturnStmt((Expr*)0);
220 }
Steve Naroff9358c712007-05-27 23:58:33 +0000221 }
Steve Naroff6f49f5d2007-05-29 14:23:36 +0000222 // we have a non-void function with an expression, continue checking
Steve Naroff9358c712007-05-27 23:58:33 +0000223 QualType rhsType = ((Expr *)RetValExp)->getType();
224
225 if (lhsType == rhsType) // common case, fast path...
226 return new ReturnStmt((Expr*)RetValExp);
Steve Naroff6f49f5d2007-05-29 14:23:36 +0000227
228 // C99 6.8.6.4p3(136): The return statement is not an assignment. The
229 // overlap restriction of subclause 6.5.16.1 does not apply to the case of
230 // function return.
Steve Naroff9358c712007-05-27 23:58:33 +0000231 AssignmentConversionResult result;
232 QualType resType = UsualAssignmentConversions(lhsType, rhsType, result);
233 bool hadError = false;
234
235 // decode the result (notice that extensions still return a type).
236 switch (result) {
237 case Compatible:
238 break;
239 case Incompatible:
240 Diag(ReturnLoc, diag::err_typecheck_return_incompatible,
241 lhsType.getAsString(), rhsType.getAsString(),
242 ((Expr *)RetValExp)->getSourceRange());
243 hadError = true;
244 break;
245 case PointerFromInt:
246 // check for null pointer constant (C99 6.3.2.3p3)
247 if (!((Expr *)RetValExp)->isNullPointerConstant())
248 Diag(ReturnLoc, diag::ext_typecheck_return_pointer_from_int);
249 break;
250 case IntFromPointer:
251 Diag(ReturnLoc, diag::ext_typecheck_return_int_from_pointer);
252 break;
253 case IncompatiblePointer:
254 Diag(ReturnLoc, diag::ext_typecheck_return_incompatible_pointer);
255 break;
256 case CompatiblePointerDiscardsQualifiers:
257 Diag(ReturnLoc, diag::ext_typecheck_return_discards_qualifiers);
258 break;
259 }
Chris Lattneraf8d5812006-11-10 05:07:45 +0000260 return new ReturnStmt((Expr*)RetValExp);
261}
262