blob: 783156f003120cf83de7e1dfea942e1510045df9 [file] [log] [blame]
Chris Lattnerddd6fc82006-11-10 04:58:55 +00001//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
Chris Lattner3e7bd4e2006-08-17 05:51:27 +00002//
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//
Chris Lattnerddd6fc82006-11-10 04:58:55 +000010// This file implements the actions class which performs semantic analysis and
11// builds an AST out of a parse stream.
Chris Lattner3e7bd4e2006-08-17 05:51:27 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattnerddd6fc82006-11-10 04:58:55 +000015#include "Sema.h"
Chris Lattnerc11438c2006-08-18 05:17:52 +000016#include "clang/AST/Decl.h"
Chris Lattner9b6d4cb2006-08-23 05:17:46 +000017#include "clang/AST/Expr.h"
Chris Lattner697e5d62006-11-09 06:32:27 +000018#include "clang/Parse/Action.h"
Chris Lattner9b6d4cb2006-08-23 05:17:46 +000019#include "clang/Parse/Scope.h"
Chris Lattnerc11438c2006-08-18 05:17:52 +000020#include "clang/Lex/IdentifierTable.h"
Chris Lattnerd3e98952006-10-06 05:22:26 +000021#include "clang/Lex/Preprocessor.h"
Chris Lattner697e5d62006-11-09 06:32:27 +000022#include "clang/Basic/TargetInfo.h"
23#include "llvm/ADT/SmallString.h"
24#include "llvm/ADT/StringExtras.h"
Chris Lattnerc11438c2006-08-18 05:17:52 +000025using namespace llvm;
26using namespace clang;
27
Chris Lattnerc11438c2006-08-18 05:17:52 +000028//===----------------------------------------------------------------------===//
29// Symbol table tracking callbacks.
30//===----------------------------------------------------------------------===//
31
Chris Lattnercc67ec12006-11-09 06:54:47 +000032bool Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
Chris Lattnerc11438c2006-08-18 05:17:52 +000033 Decl *D = II.getFETokenInfo<Decl>();
Chris Lattnera11999d2006-10-15 22:34:45 +000034 return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
Chris Lattnerc11438c2006-08-18 05:17:52 +000035}
36
Chris Lattner2dacc3f2006-10-16 00:33:54 +000037Action::DeclTy *
Chris Lattnercc67ec12006-11-09 06:54:47 +000038Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
39 DeclTy *LastInGroup) {
Chris Lattnerc11438c2006-08-18 05:17:52 +000040 IdentifierInfo *II = D.getIdentifier();
41 Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
42
Chris Lattnera11999d2006-10-15 22:34:45 +000043 Decl *New;
44 if (D.isFunctionDeclarator())
Chris Lattner2dacc3f2006-10-16 00:33:54 +000045 New = new FunctionDecl(II, D, PrevDecl);
Chris Lattnera11999d2006-10-15 22:34:45 +000046 else
Chris Lattner2dacc3f2006-10-16 00:33:54 +000047 New = new VarDecl(II, D, PrevDecl);
Chris Lattnerc11438c2006-08-18 05:17:52 +000048
49 // If this has an identifier, add it to the scope stack.
50 if (II) {
51 // If PrevDecl includes conflicting name here, emit a diagnostic.
52 II->setFETokenInfo(New);
53 S->AddDecl(II);
54 }
Chris Lattner2dacc3f2006-10-16 00:33:54 +000055
Chris Lattner0535ebb2006-10-25 05:28:22 +000056 // If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
57 // remember this in the LastInGroupList list.
58 if (LastInGroup && S->getParent() == 0)
59 LastInGroupList.push_back((Decl*)LastInGroup);
Chris Lattner2dacc3f2006-10-16 00:33:54 +000060
61 return New;
62}
63
64Action::DeclTy *
Chris Lattnercc67ec12006-11-09 06:54:47 +000065Sema::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
Chris Lattner2dacc3f2006-10-16 00:33:54 +000066 FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
Chris Lattner30f910e2006-10-16 05:52:41 +000067
68 FD->setBody((Stmt*)Body);
69
Chris Lattner2dacc3f2006-10-16 00:33:54 +000070 return FD;
Chris Lattnerc11438c2006-08-18 05:17:52 +000071}
72
Chris Lattnercc67ec12006-11-09 06:54:47 +000073void Sema::PopScope(SourceLocation Loc, Scope *S) {
Chris Lattnerc11438c2006-08-18 05:17:52 +000074 for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
75 I != E; ++I) {
76 IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
77 Decl *D = II.getFETokenInfo<Decl>();
78 assert(D && "This decl didn't get pushed??");
79
80 Decl *Next = D->getNext();
81
82 // FIXME: Push the decl on the parent function list if in a function.
83 delete D;
84
85 II.setFETokenInfo(Next);
86 }
87}
88
Chris Lattner9b6d4cb2006-08-23 05:17:46 +000089//===--------------------------------------------------------------------===//
Chris Lattnere5cca062006-10-25 04:29:46 +000090// Statement Parsing Callbacks.
91//===--------------------------------------------------------------------===//
92
93Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +000094Sema::ParseCompoundStmt(SourceLocation L, SourceLocation R,
95 StmtTy **Elts, unsigned NumElts) {
Chris Lattner72b7d392006-11-04 06:37:16 +000096 if (NumElts > 1)
Chris Lattnere5cca062006-10-25 04:29:46 +000097 return new CompoundStmt((Stmt**)Elts, NumElts);
98 else if (NumElts == 1)
99 return Elts[0]; // {stmt} -> stmt
100 else
101 return 0; // {} -> ;
102}
103
Chris Lattner6c0ff132006-11-05 00:19:50 +0000104Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000105Sema::ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
106 SourceLocation DotDotDotLoc, ExprTy *RHSVal,
107 SourceLocation ColonLoc, StmtTy *SubStmt) {
Chris Lattner6c0ff132006-11-05 00:19:50 +0000108 return new CaseStmt((Expr*)LHSVal, (Expr*)RHSVal, (Stmt*)SubStmt);
109}
110
111Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000112Sema::ParseDefaultStmt(SourceLocation DefaultLoc,
113 SourceLocation ColonLoc, StmtTy *SubStmt) {
Chris Lattner6c0ff132006-11-05 00:19:50 +0000114 return new DefaultStmt((Stmt*)SubStmt);
115}
116
117Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000118Sema::ParseLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
119 SourceLocation ColonLoc, StmtTy *SubStmt) {
Chris Lattner6c0ff132006-11-05 00:19:50 +0000120 return new LabelStmt(II, (Stmt*)SubStmt);
121}
122
Chris Lattner5f84a062006-10-25 05:55:20 +0000123Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000124Sema::ParseIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
125 StmtTy *ThenVal, SourceLocation ElseLoc,
126 StmtTy *ElseVal) {
Chris Lattner5f84a062006-10-25 05:55:20 +0000127 return new IfStmt((Expr*)CondVal, (Stmt*)ThenVal, (Stmt*)ElseVal);
128}
Chris Lattnerf2174b62006-11-04 20:59:27 +0000129Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000130Sema::ParseSwitchStmt(SourceLocation SwitchLoc, ExprTy *Cond, StmtTy *Body) {
Chris Lattnerf2174b62006-11-04 20:59:27 +0000131 return new SwitchStmt((Expr*)Cond, (Stmt*)Body);
132}
Chris Lattnere5cca062006-10-25 04:29:46 +0000133
134Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000135Sema::ParseWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, StmtTy *Body){
Chris Lattner85ed8732006-11-04 20:40:44 +0000136 return new WhileStmt((Expr*)Cond, (Stmt*)Body);
137}
138
139Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000140Sema::ParseDoStmt(SourceLocation DoLoc, StmtTy *Body,
141 SourceLocation WhileLoc, ExprTy *Cond) {
Chris Lattner85ed8732006-11-04 20:40:44 +0000142 return new DoStmt((Stmt*)Body, (Expr*)Cond);
143}
144
Chris Lattner16976d32006-11-05 01:46:01 +0000145Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000146Sema::ParseForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
147 StmtTy *First, ExprTy *Second, ExprTy *Third,
148 SourceLocation RParenLoc, StmtTy *Body) {
Chris Lattner16976d32006-11-05 01:46:01 +0000149 return new ForStmt((Stmt*)First, (Expr*)Second, (Expr*)Third, (Stmt*)Body);
150}
151
152
153Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000154Sema::ParseGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
155 IdentifierInfo *LabelII) {
Chris Lattner16976d32006-11-05 01:46:01 +0000156 return new GotoStmt(LabelII);
157}
158Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000159Sema::ParseIndirectGotoStmt(SourceLocation GotoLoc,SourceLocation StarLoc,
160 ExprTy *DestExp) {
Chris Lattner16976d32006-11-05 01:46:01 +0000161 return new IndirectGotoStmt((Expr*)DestExp);
162}
163
164Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000165Sema::ParseContinueStmt(SourceLocation ContinueLoc) {
Chris Lattner16976d32006-11-05 01:46:01 +0000166 return new ContinueStmt();
167}
168
169Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000170Sema::ParseBreakStmt(SourceLocation GotoLoc) {
Chris Lattner16976d32006-11-05 01:46:01 +0000171 return new BreakStmt();
172}
173
174
Chris Lattner85ed8732006-11-04 20:40:44 +0000175Action::StmtResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000176Sema::ParseReturnStmt(SourceLocation ReturnLoc, ExprTy *RetValExp) {
Chris Lattner6d9a6852006-10-25 05:11:20 +0000177 return new ReturnStmt((Expr*)RetValExp);
Chris Lattnere5cca062006-10-25 04:29:46 +0000178}
179
180//===--------------------------------------------------------------------===//
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000181// Expression Parsing Callbacks.
182//===--------------------------------------------------------------------===//
183
Chris Lattnercc67ec12006-11-09 06:54:47 +0000184Action::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
185 tok::TokenKind Kind) {
Chris Lattnerae319692006-10-25 03:49:28 +0000186 switch (Kind) {
Chris Lattner879b9ad2006-08-24 04:53:44 +0000187 default:
188 assert(0 && "Unknown simple primary expr!");
189 case tok::identifier: {
190 // Could be enum-constant or decl.
191 //Tok.getIdentifierInfo()
Chris Lattnerf42cce72006-10-25 04:09:21 +0000192 return new DeclRefExpr(*(Decl*)0);
Chris Lattner879b9ad2006-08-24 04:53:44 +0000193 }
194
195 case tok::char_constant: // constant: character-constant
196 case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
197 case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
198 case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
Chris Lattner94b4ce32006-10-06 05:51:35 +0000199 //assert(0 && "FIXME: Unimp so far!");
Chris Lattnerf42cce72006-10-25 04:09:21 +0000200 return new DeclRefExpr(*(Decl*)0);
Chris Lattner879b9ad2006-08-24 04:53:44 +0000201 }
202}
203
Chris Lattnercc67ec12006-11-09 06:54:47 +0000204Action::ExprResult Sema::ParseIntegerConstant(SourceLocation Loc) {
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000205 return new IntegerConstant();
206}
Chris Lattnercc67ec12006-11-09 06:54:47 +0000207Action::ExprResult Sema::ParseFloatingConstant(SourceLocation Loc) {
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000208 return new FloatingConstant();
209}
210
Chris Lattnercc67ec12006-11-09 06:54:47 +0000211Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,
212 ExprTy *Val) {
Chris Lattner72b7d392006-11-04 06:37:16 +0000213 return Val;
Chris Lattner1b926492006-08-23 06:42:10 +0000214}
215
Chris Lattner697e5d62006-11-09 06:32:27 +0000216
217
218
219/// HexDigitValue - Return the value of the specified hex digit, or -1 if it's
220/// not valid.
221static int HexDigitValue(char C) {
222 if (C >= '0' && C <= '9') return C-'0';
223 if (C >= 'a' && C <= 'f') return C-'a'+10;
224 if (C >= 'A' && C <= 'F') return C-'A'+10;
225 return -1;
226}
227
228/// ParseStringExpr - The specified tokens were lexed as pasted string
229/// fragments (e.g. "foo" "bar" L"baz").
230
Chris Lattnerd3e98952006-10-06 05:22:26 +0000231/// ParseStringExpr - This accepts a string after semantic analysis. This string
232/// may be the result of string concatenation ([C99 5.1.1.2, translation phase
233/// #6]), so it may come from multiple tokens.
234///
Chris Lattner697e5d62006-11-09 06:32:27 +0000235Action::ExprResult
Chris Lattnercc67ec12006-11-09 06:54:47 +0000236Sema::ParseStringExpr(const LexerToken *StringToks, unsigned NumStringToks) {
Chris Lattner697e5d62006-11-09 06:32:27 +0000237 assert(NumStringToks && "Must have at least one string!");
Chris Lattnerd3e98952006-10-06 05:22:26 +0000238
Chris Lattner697e5d62006-11-09 06:32:27 +0000239 // Scan all of the string portions, remember the max individual token length,
240 // computing a bound on the concatenated string length, and see whether any
241 // piece is a wide-string. If any of the string portions is a wide-string
242 // literal, the result is a wide-string literal [C99 6.4.5p4].
243 unsigned MaxTokenLength = StringToks[0].getLength();
244 unsigned SizeBound = StringToks[0].getLength()-2; // -2 for "".
245 bool AnyWide = StringToks[0].getKind() == tok::wide_string_literal;
246
247 // The common case is that there is only one string fragment.
248 for (unsigned i = 1; i != NumStringToks; ++i) {
249 // The string could be shorter than this if it needs cleaning, but this is a
250 // reasonable bound, which is all we need.
251 SizeBound += StringToks[i].getLength()-2; // -2 for "".
252
253 // Remember maximum string piece length.
254 if (StringToks[i].getLength() > MaxTokenLength)
255 MaxTokenLength = StringToks[i].getLength();
256
257 // Remember if we see any wide strings.
258 AnyWide |= StringToks[i].getKind() == tok::wide_string_literal;
259 }
260
261
262 // Include space for the null terminator.
263 ++SizeBound;
264
265 // TODO: K&R warning: "traditional C rejects string constant concatenation"
266
267 // Get the width in bytes of wchar_t. If no wchar_t strings are used, do not
268 // query the target. As such, wchar_tByteWidth is only valid if AnyWide=true.
269 unsigned wchar_tByteWidth = ~0U;
270 if (AnyWide)
271 wchar_tByteWidth =
272 PP.getTargetInfo().getWCharWidth(StringToks[0].getLocation());
273
274 // The output buffer size needs to be large enough to hold wide characters.
275 // This is a worst-case assumption which basically corresponds to L"" "long".
276 if (AnyWide)
277 SizeBound *= wchar_tByteWidth;
278
279 // Create a temporary buffer to hold the result string data.
280 SmallString<512> ResultBuf;
281 ResultBuf.resize(SizeBound);
282
283 // Likewise, but for each string piece.
284 SmallString<512> TokenBuf;
285 TokenBuf.resize(MaxTokenLength);
286
287 // Loop over all the strings, getting their spelling, and expanding them to
288 // wide strings as appropriate.
289 char *ResultPtr = &ResultBuf[0]; // Next byte to fill in.
290
291 for (unsigned i = 0, e = NumStringToks; i != e; ++i) {
292 const char *ThisTokBuf = &TokenBuf[0];
293 // Get the spelling of the token, which eliminates trigraphs, etc. We know
294 // that ThisTokBuf points to a buffer that is big enough for the whole token
295 // and 'spelled' tokens can only shrink.
296 unsigned ThisTokLen = PP.getSpelling(StringToks[i], ThisTokBuf);
297 const char *ThisTokEnd = ThisTokBuf+ThisTokLen-1; // Skip end quote.
298
299 // TODO: Input character set mapping support.
300
301 // Skip L marker for wide strings.
302 if (ThisTokBuf[0] == 'L') ++ThisTokBuf;
303
304 assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
305 ++ThisTokBuf;
306
307 while (ThisTokBuf != ThisTokEnd) {
308 // Is this a span of non-escape characters?
309 if (ThisTokBuf[0] != '\\') {
310 const char *InStart = ThisTokBuf;
311 do {
312 ++ThisTokBuf;
313 } while (ThisTokBuf != ThisTokEnd && ThisTokBuf[0] != '\\');
314
315 // Copy the character span over.
316 unsigned Len = ThisTokBuf-InStart;
317 if (!AnyWide) {
318 memcpy(ResultPtr, InStart, Len);
319 ResultPtr += Len;
320 } else {
321 // Note: our internal rep of wide char tokens is always little-endian.
322 for (; Len; --Len, ++InStart) {
323 *ResultPtr++ = InStart[0];
324 // Add zeros at the end.
325 for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
326 *ResultPtr++ = 0;
327 }
328 }
329 continue;
330 }
331
332 // Otherwise, this is an escape character. Skip the '\' char.
333 ++ThisTokBuf;
334
335 // We know that this character can't be off the end of the buffer, because
336 // that would have been \", which would not have been the end of string.
337 unsigned ResultChar = *ThisTokBuf++;
338 switch (ResultChar) {
339 // These map to themselves.
340 case '\\': case '\'': case '"': case '?': break;
341
342 // These have fixed mappings.
343 case 'a':
344 // TODO: K&R: the meaning of '\\a' is different in traditional C
345 ResultChar = 7;
346 break;
347 case 'b':
348 ResultChar = 8;
349 break;
350 case 'e':
351 PP.Diag(StringToks[i], diag::ext_nonstandard_escape, "e");
352 ResultChar = 27;
353 break;
354 case 'f':
355 ResultChar = 12;
356 break;
357 case 'n':
358 ResultChar = 10;
359 break;
360 case 'r':
361 ResultChar = 13;
362 break;
363 case 't':
364 ResultChar = 9;
365 break;
366 case 'v':
367 ResultChar = 11;
368 break;
369
370 //case 'u': case 'U': // FIXME: UCNs.
371 case 'x': // Hex escape.
372 if (ThisTokBuf == ThisTokEnd ||
373 (ResultChar = HexDigitValue(*ThisTokBuf)) == ~0U) {
374 PP.Diag(StringToks[i], diag::err_hex_escape_no_digits);
375 ResultChar = 0;
376 break;
377 }
378 ++ThisTokBuf; // Consumed one hex digit.
379
380 assert(0 && "hex escape: unimp!");
381 break;
382 case '0': case '1': case '2': case '3':
383 case '4': case '5': case '6': case '7':
384 // Octal escapes.
385 assert(0 && "octal escape: unimp!");
386 break;
387
388 // Otherwise, these are not valid escapes.
389 case '(': case '{': case '[': case '%':
390 // GCC accepts these as extensions. We warn about them as such though.
391 if (!PP.getLangOptions().NoExtensions) {
392 PP.Diag(StringToks[i], diag::ext_nonstandard_escape,
393 std::string()+(char)ResultChar);
394 break;
395 }
396 // FALL THROUGH.
397 default:
398 if (isgraph(ThisTokBuf[0])) {
399 PP.Diag(StringToks[i], diag::ext_unknown_escape,
400 std::string()+(char)ResultChar);
401 } else {
402 PP.Diag(StringToks[i], diag::ext_unknown_escape,
403 "x"+utohexstr(ResultChar));
404 }
405 }
406
407 // Note: our internal rep of wide char tokens is always little-endian.
408 *ResultPtr++ = ResultChar & 0xFF;
409
410 if (AnyWide) {
411 for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
412 *ResultPtr++ = ResultChar >> i*8;
413 }
414 }
415 }
416
417 // Add zero terminator.
418 *ResultPtr = 0;
419 if (AnyWide) {
420 for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
421 *ResultPtr++ = 0;
422 }
423
424 SmallVector<SourceLocation, 4> StringTokLocs;
425 for (unsigned i = 0; i != NumStringToks; ++i)
426 StringTokLocs.push_back(StringToks[i].getLocation());
427
428 // FIXME: use factory.
429
430 // Pass &StringTokLocs[0], StringTokLocs.size() to factory!
431 return new StringExpr(&ResultBuf[0], ResultPtr-&ResultBuf[0], AnyWide);
432}
Chris Lattnerd3e98952006-10-06 05:22:26 +0000433
Chris Lattner1b926492006-08-23 06:42:10 +0000434// Unary Operators. 'Tok' is the token for the operator.
Chris Lattnercc67ec12006-11-09 06:54:47 +0000435Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
436 ExprTy *Input) {
Chris Lattner1b926492006-08-23 06:42:10 +0000437 UnaryOperator::Opcode Opc;
Chris Lattner0ba3dc42006-10-25 03:38:23 +0000438 switch (Op) {
Chris Lattner1b926492006-08-23 06:42:10 +0000439 default: assert(0 && "Unknown unary op!");
Chris Lattner26115ac2006-08-24 06:10:04 +0000440 case tok::plusplus: Opc = UnaryOperator::PreInc; break;
441 case tok::minusminus: Opc = UnaryOperator::PreDec; break;
442 case tok::amp: Opc = UnaryOperator::AddrOf; break;
443 case tok::star: Opc = UnaryOperator::Deref; break;
444 case tok::plus: Opc = UnaryOperator::Plus; break;
445 case tok::minus: Opc = UnaryOperator::Minus; break;
446 case tok::tilde: Opc = UnaryOperator::Not; break;
447 case tok::exclaim: Opc = UnaryOperator::LNot; break;
Chris Lattner26115ac2006-08-24 06:10:04 +0000448 case tok::kw_sizeof: Opc = UnaryOperator::SizeOf; break;
449 case tok::kw___alignof: Opc = UnaryOperator::AlignOf; break;
Chris Lattnera11999d2006-10-15 22:34:45 +0000450 case tok::kw___real: Opc = UnaryOperator::Real; break;
451 case tok::kw___imag: Opc = UnaryOperator::Imag; break;
452 case tok::ampamp: Opc = UnaryOperator::AddrLabel; break;
Chris Lattnerc52b1182006-10-25 05:45:55 +0000453 case tok::kw___extension__:
Chris Lattner72b7d392006-11-04 06:37:16 +0000454 return Input;
455 //Opc = UnaryOperator::Extension;
456 //break;
Chris Lattner1b926492006-08-23 06:42:10 +0000457 }
458
Chris Lattner72b7d392006-11-04 06:37:16 +0000459 return new UnaryOperator((Expr*)Input, Opc);
Chris Lattner1b926492006-08-23 06:42:10 +0000460}
461
Chris Lattnercc67ec12006-11-09 06:54:47 +0000462Action::ExprResult Sema::
Chris Lattner26da7302006-08-24 06:49:19 +0000463ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
464 SourceLocation LParenLoc, TypeTy *Ty,
465 SourceLocation RParenLoc) {
Chris Lattner72b7d392006-11-04 06:37:16 +0000466 return new SizeOfAlignOfTypeExpr(isSizeof, (Type*)Ty);
Chris Lattner26da7302006-08-24 06:49:19 +0000467}
468
469
Chris Lattnercc67ec12006-11-09 06:54:47 +0000470Action::ExprResult Sema::ParsePostfixUnaryOp(SourceLocation OpLoc,
471 tok::TokenKind Kind,
472 ExprTy *Input) {
Chris Lattner1b926492006-08-23 06:42:10 +0000473 UnaryOperator::Opcode Opc;
Chris Lattnerae319692006-10-25 03:49:28 +0000474 switch (Kind) {
Chris Lattner1b926492006-08-23 06:42:10 +0000475 default: assert(0 && "Unknown unary op!");
476 case tok::plusplus: Opc = UnaryOperator::PostInc; break;
477 case tok::minusminus: Opc = UnaryOperator::PostDec; break;
478 }
479
Chris Lattner72b7d392006-11-04 06:37:16 +0000480 return new UnaryOperator((Expr*)Input, Opc);
Chris Lattner1b926492006-08-23 06:42:10 +0000481}
482
Chris Lattnercc67ec12006-11-09 06:54:47 +0000483Action::ExprResult Sema::
Chris Lattnere165d942006-08-24 04:40:38 +0000484ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
485 ExprTy *Idx, SourceLocation RLoc) {
Chris Lattner72b7d392006-11-04 06:37:16 +0000486 return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx);
Chris Lattnere165d942006-08-24 04:40:38 +0000487}
488
Chris Lattnercc67ec12006-11-09 06:54:47 +0000489Action::ExprResult Sema::
Chris Lattnere165d942006-08-24 04:40:38 +0000490ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
491 tok::TokenKind OpKind, SourceLocation MemberLoc,
492 IdentifierInfo &Member) {
Chris Lattner6f3a1172006-08-24 05:19:28 +0000493 Decl *MemberDecl = 0;
494 // TODO: Look up MemberDecl.
Chris Lattner72b7d392006-11-04 06:37:16 +0000495 return new MemberExpr((Expr*)Base, OpKind == tok::arrow, MemberDecl);
Chris Lattnere165d942006-08-24 04:40:38 +0000496}
497
498/// ParseCallExpr - Handle a call to Fn with the specified array of arguments.
499/// This provides the location of the left/right parens and a list of comma
500/// locations.
Chris Lattnercc67ec12006-11-09 06:54:47 +0000501Action::ExprResult Sema::
Chris Lattnere165d942006-08-24 04:40:38 +0000502ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
503 ExprTy **Args, unsigned NumArgs,
504 SourceLocation *CommaLocs, SourceLocation RParenLoc) {
Chris Lattner72b7d392006-11-04 06:37:16 +0000505 return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgs);
Chris Lattnere165d942006-08-24 04:40:38 +0000506}
507
Chris Lattnercc67ec12006-11-09 06:54:47 +0000508Action::ExprResult Sema::
Chris Lattnere550a4e2006-08-24 06:37:51 +0000509ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
510 SourceLocation RParenLoc, ExprTy *Op) {
Chris Lattner72b7d392006-11-04 06:37:16 +0000511 return new CastExpr((Type*)Ty, (Expr*)Op);
Chris Lattnere550a4e2006-08-24 06:37:51 +0000512}
513
514
Chris Lattnere165d942006-08-24 04:40:38 +0000515
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000516// Binary Operators. 'Tok' is the token for the operator.
Chris Lattnercc67ec12006-11-09 06:54:47 +0000517Action::ExprResult Sema::ParseBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
518 ExprTy *LHS, ExprTy *RHS) {
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000519 BinaryOperator::Opcode Opc;
Chris Lattnerae319692006-10-25 03:49:28 +0000520 switch (Kind) {
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000521 default: assert(0 && "Unknown binop!");
522 case tok::star: Opc = BinaryOperator::Mul; break;
523 case tok::slash: Opc = BinaryOperator::Div; break;
524 case tok::percent: Opc = BinaryOperator::Rem; break;
525 case tok::plus: Opc = BinaryOperator::Add; break;
526 case tok::minus: Opc = BinaryOperator::Sub; break;
527 case tok::lessless: Opc = BinaryOperator::Shl; break;
528 case tok::greatergreater: Opc = BinaryOperator::Shr; break;
529 case tok::lessequal: Opc = BinaryOperator::LE; break;
530 case tok::less: Opc = BinaryOperator::LT; break;
531 case tok::greaterequal: Opc = BinaryOperator::GE; break;
532 case tok::greater: Opc = BinaryOperator::GT; break;
533 case tok::exclaimequal: Opc = BinaryOperator::NE; break;
534 case tok::equalequal: Opc = BinaryOperator::EQ; break;
535 case tok::amp: Opc = BinaryOperator::And; break;
536 case tok::caret: Opc = BinaryOperator::Xor; break;
537 case tok::pipe: Opc = BinaryOperator::Or; break;
538 case tok::ampamp: Opc = BinaryOperator::LAnd; break;
539 case tok::pipepipe: Opc = BinaryOperator::LOr; break;
540 case tok::equal: Opc = BinaryOperator::Assign; break;
541 case tok::starequal: Opc = BinaryOperator::MulAssign; break;
542 case tok::slashequal: Opc = BinaryOperator::DivAssign; break;
543 case tok::percentequal: Opc = BinaryOperator::RemAssign; break;
544 case tok::plusequal: Opc = BinaryOperator::AddAssign; break;
545 case tok::minusequal: Opc = BinaryOperator::SubAssign; break;
546 case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break;
547 case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break;
548 case tok::ampequal: Opc = BinaryOperator::AndAssign; break;
549 case tok::caretequal: Opc = BinaryOperator::XorAssign; break;
550 case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
551 case tok::comma: Opc = BinaryOperator::Comma; break;
552 }
553
Chris Lattner72b7d392006-11-04 06:37:16 +0000554 return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000555}
556
557/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
558/// in the case of a the GNU conditional expr extension.
Chris Lattnercc67ec12006-11-09 06:54:47 +0000559Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc,
560 SourceLocation ColonLoc,
561 ExprTy *Cond, ExprTy *LHS,
562 ExprTy *RHS) {
Chris Lattner72b7d392006-11-04 06:37:16 +0000563 return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
Chris Lattner9b6d4cb2006-08-23 05:17:46 +0000564}
565