blob: 49c1583bb7ac87787ce6a372c605ddf823ecd748 [file] [log] [blame]
Chris Lattner5b183d82006-11-10 05:03:26 +00001//===--- SemaExpr.cpp - Semantic Analysis for Expressions -----------------===//
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 expressions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
Chris Lattnercb6a3822006-11-10 06:20:45 +000015#include "clang/AST/ASTContext.h"
Chris Lattner17ed4872006-11-20 04:58:19 +000016#include "clang/AST/Decl.h"
Chris Lattner5b183d82006-11-10 05:03:26 +000017#include "clang/AST/Expr.h"
18#include "clang/Lex/Preprocessor.h"
Steve Naroff09ef4742007-03-09 23:16:33 +000019#include "clang/Lex/LiteralSupport.h"
Steve Narofff2fb89e2007-03-13 20:29:44 +000020#include "clang/Basic/SourceManager.h"
Chris Lattner5b183d82006-11-10 05:03:26 +000021#include "clang/Basic/Diagnostic.h"
Chris Lattnerac18be92006-11-20 06:49:47 +000022#include "clang/Basic/LangOptions.h"
Chris Lattner5b183d82006-11-10 05:03:26 +000023#include "clang/Basic/TargetInfo.h"
24#include "llvm/ADT/SmallString.h"
Chris Lattner5b183d82006-11-10 05:03:26 +000025using namespace llvm;
26using namespace clang;
27
Steve Naroffdf7855b2007-02-21 23:46:25 +000028/// ParseStringLiteral - The specified tokens were lexed as pasted string
Chris Lattner5b183d82006-11-10 05:03:26 +000029/// fragments (e.g. "foo" "bar" L"baz"). The result string has to handle string
30/// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from
31/// multiple tokens. However, the common case is that StringToks points to one
32/// string.
33///
34Action::ExprResult
Steve Naroffdf7855b2007-02-21 23:46:25 +000035Sema::ParseStringLiteral(const LexerToken *StringToks, unsigned NumStringToks) {
Chris Lattner5b183d82006-11-10 05:03:26 +000036 assert(NumStringToks && "Must have at least one string!");
37
Steve Naroff4f88b312007-03-13 22:37:02 +000038 StringLiteralParser Literal(StringToks, NumStringToks, PP, Context.Target);
39 if (Literal.hadError)
40 return ExprResult(true);
Chris Lattner5b183d82006-11-10 05:03:26 +000041
Chris Lattner5b183d82006-11-10 05:03:26 +000042 SmallVector<SourceLocation, 4> StringTokLocs;
43 for (unsigned i = 0; i != NumStringToks; ++i)
44 StringTokLocs.push_back(StringToks[i].getLocation());
Steve Narofff1e53692007-03-23 22:27:02 +000045
46 // FIXME: handle wchar_t
47 TypeRef t = Context.getPointerType(Context.CharTy);
48
Chris Lattner5b183d82006-11-10 05:03:26 +000049 // FIXME: use factory.
Chris Lattner5b183d82006-11-10 05:03:26 +000050 // Pass &StringTokLocs[0], StringTokLocs.size() to factory!
Steve Naroff4f88b312007-03-13 22:37:02 +000051 return new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
Steve Narofff1e53692007-03-23 22:27:02 +000052 Literal.AnyWide, t);
Chris Lattner5b183d82006-11-10 05:03:26 +000053}
54
Chris Lattnere168f762006-11-10 05:29:30 +000055
Chris Lattnerac18be92006-11-20 06:49:47 +000056/// ParseIdentifierExpr - The parser read an identifier in expression context,
57/// validate it per-C99 6.5.1. HasTrailingLParen indicates whether this
58/// identifier is used in an function call context.
59Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,
60 IdentifierInfo &II,
61 bool HasTrailingLParen) {
Chris Lattner17ed4872006-11-20 04:58:19 +000062 // Could be enum-constant or decl.
Chris Lattner9561a0b2007-01-28 08:20:04 +000063 Decl *D = LookupScopedDecl(&II, Decl::IDNS_Ordinary, Loc, S);
Chris Lattner17ed4872006-11-20 04:58:19 +000064 if (D == 0) {
Bill Wendling4073ed52007-02-13 01:51:42 +000065 // Otherwise, this could be an implicitly declared function reference (legal
Chris Lattner9561a0b2007-01-28 08:20:04 +000066 // in C90, extension in C99).
Chris Lattnerac18be92006-11-20 06:49:47 +000067 if (HasTrailingLParen &&
68 // Not in C++.
Steve Narofff1e53692007-03-23 22:27:02 +000069 !getLangOptions().CPlusPlus)
Chris Lattnerac18be92006-11-20 06:49:47 +000070 D = ImplicitlyDefineFunction(Loc, II, S);
Steve Narofff1e53692007-03-23 22:27:02 +000071 else
Chris Lattnerac18be92006-11-20 06:49:47 +000072 // If this name wasn't predeclared and if this is not a function call,
73 // diagnose the problem.
Steve Narofff1e53692007-03-23 22:27:02 +000074 return Diag(Loc, diag::err_undeclared_var_use, II.getName());
Chris Lattner17ed4872006-11-20 04:58:19 +000075 }
76
Steve Narofff1e53692007-03-23 22:27:02 +000077 if (ObjectDecl *OD = dyn_cast<ObjectDecl>(D)) {
78 return new DeclRefExpr(OD);
79 } else if (isa<TypedefDecl>(D))
80 return Diag(Loc, diag::err_unexpected_typedef, II.getName());
81
82 assert(0 && "Invalid decl");
Chris Lattner17ed4872006-11-20 04:58:19 +000083}
Chris Lattnere168f762006-11-10 05:29:30 +000084
Chris Lattner17ed4872006-11-20 04:58:19 +000085Sema::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
86 tok::TokenKind Kind) {
Chris Lattnere168f762006-11-10 05:29:30 +000087 switch (Kind) {
88 default:
89 assert(0 && "Unknown simple primary expr!");
Chris Lattnere168f762006-11-10 05:29:30 +000090 case tok::char_constant: // constant: character-constant
Chris Lattner17ed4872006-11-20 04:58:19 +000091 // TODO: MOVE this to be some other callback.
Chris Lattnere168f762006-11-10 05:29:30 +000092 case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
93 case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU]
94 case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
Chris Lattner17ed4872006-11-20 04:58:19 +000095 return 0;
Chris Lattnere168f762006-11-10 05:29:30 +000096 }
97}
98
Steve Naroff8160ea22007-03-06 01:09:46 +000099Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
Steve Narofff2fb89e2007-03-13 20:29:44 +0000100 // fast path for a single digit (which is quite common). A single digit
101 // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
102 if (Tok.getLength() == 1) {
103 const char *t = PP.getSourceManager().getCharacterData(Tok.getLocation());
104 return ExprResult(new IntegerLiteral(*t-'0', Context.IntTy));
105 }
Steve Naroff8160ea22007-03-06 01:09:46 +0000106 SmallString<512> IntegerBuffer;
107 IntegerBuffer.resize(Tok.getLength());
108 const char *ThisTokBegin = &IntegerBuffer[0];
109
110 // Get the spelling of the token, which eliminates trigraphs, etc. Notes:
111 // - We know that ThisTokBuf points to a buffer that is big enough for the
112 // whole token and 'spelled' tokens can only shrink.
113 // - In practice, the local buffer is only used when the spelling doesn't
114 // match the original token (which is rare). The common case simply returns
115 // a pointer to a *constant* buffer (avoiding a copy).
116
117 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
Steve Naroff09ef4742007-03-09 23:16:33 +0000118 NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
Steve Naroff451d8f162007-03-12 23:22:38 +0000119 Tok.getLocation(), PP);
Steve Narofff2fb89e2007-03-13 20:29:44 +0000120 if (Literal.hadError)
121 return ExprResult(true);
122
Steve Naroff09ef4742007-03-09 23:16:33 +0000123 if (Literal.isIntegerLiteral()) {
124 TypeRef t;
125 if (Literal.hasSuffix()) {
126 if (Literal.isLong)
127 t = Literal.isUnsigned ? Context.UnsignedLongTy : Context.LongTy;
128 else if (Literal.isLongLong)
129 t = Literal.isUnsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
130 else
131 t = Context.UnsignedIntTy;
132 } else {
133 t = Context.IntTy; // implicit type is "int"
134 }
Steve Naroff451d8f162007-03-12 23:22:38 +0000135 uintmax_t val;
136 if (Literal.GetIntegerValue(val)) {
Steve Narofff2fb89e2007-03-13 20:29:44 +0000137 return new IntegerLiteral(val, t);
Steve Naroff09ef4742007-03-09 23:16:33 +0000138 }
139 } else if (Literal.isFloatingLiteral()) {
Steve Narofff1e53692007-03-23 22:27:02 +0000140 // FIXME: fill in the value and compute the real type...
141 return new FloatingLiteral(7.7, Context.FloatTy);
Steve Naroff09ef4742007-03-09 23:16:33 +0000142 }
Steve Narofff2fb89e2007-03-13 20:29:44 +0000143 return ExprResult(true);
Chris Lattnere168f762006-11-10 05:29:30 +0000144}
145
146Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,
147 ExprTy *Val) {
148 return Val;
149}
150
151
152// Unary Operators. 'Tok' is the token for the operator.
153Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
154 ExprTy *Input) {
155 UnaryOperator::Opcode Opc;
156 switch (Op) {
157 default: assert(0 && "Unknown unary op!");
158 case tok::plusplus: Opc = UnaryOperator::PreInc; break;
159 case tok::minusminus: Opc = UnaryOperator::PreDec; break;
160 case tok::amp: Opc = UnaryOperator::AddrOf; break;
161 case tok::star: Opc = UnaryOperator::Deref; break;
162 case tok::plus: Opc = UnaryOperator::Plus; break;
163 case tok::minus: Opc = UnaryOperator::Minus; break;
164 case tok::tilde: Opc = UnaryOperator::Not; break;
165 case tok::exclaim: Opc = UnaryOperator::LNot; break;
166 case tok::kw_sizeof: Opc = UnaryOperator::SizeOf; break;
167 case tok::kw___alignof: Opc = UnaryOperator::AlignOf; break;
168 case tok::kw___real: Opc = UnaryOperator::Real; break;
169 case tok::kw___imag: Opc = UnaryOperator::Imag; break;
170 case tok::ampamp: Opc = UnaryOperator::AddrLabel; break;
171 case tok::kw___extension__:
172 return Input;
173 //Opc = UnaryOperator::Extension;
174 //break;
175 }
176
177 return new UnaryOperator((Expr*)Input, Opc);
178}
179
180Action::ExprResult Sema::
181ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
182 SourceLocation LParenLoc, TypeTy *Ty,
183 SourceLocation RParenLoc) {
Chris Lattner0d8b1a12006-11-20 04:34:45 +0000184 // If error parsing type, ignore.
185 if (Ty == 0) return true;
Chris Lattner6531c102007-01-23 22:29:49 +0000186
187 // Verify that this is a valid expression.
188 TypeRef ArgTy = TypeRef::getFromOpaquePtr(Ty);
189
190 if (isa<FunctionType>(ArgTy) && isSizeof) {
191 // alignof(function) is allowed.
192 Diag(OpLoc, diag::ext_sizeof_function_type);
Steve Naroff26c8ea52007-03-21 21:08:52 +0000193 return new IntegerLiteral(1, Context.IntTy);
Chris Lattner6531c102007-01-23 22:29:49 +0000194 } else if (ArgTy->isVoidType()) {
195 Diag(OpLoc, diag::ext_sizeof_void_type, isSizeof ? "sizeof" : "__alignof");
196 } else if (ArgTy->isIncompleteType()) {
197 std::string TypeName;
198 ArgTy->getAsString(TypeName);
199 Diag(OpLoc, isSizeof ? diag::err_sizeof_incomplete_type :
200 diag::err_alignof_incomplete_type, TypeName);
Steve Naroff26c8ea52007-03-21 21:08:52 +0000201 return new IntegerLiteral(0, Context.IntTy);
Chris Lattner6531c102007-01-23 22:29:49 +0000202 }
203
Steve Narofff1e53692007-03-23 22:27:02 +0000204 return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, Context.IntTy);
Chris Lattnere168f762006-11-10 05:29:30 +0000205}
206
207
208Action::ExprResult Sema::ParsePostfixUnaryOp(SourceLocation OpLoc,
209 tok::TokenKind Kind,
210 ExprTy *Input) {
211 UnaryOperator::Opcode Opc;
212 switch (Kind) {
213 default: assert(0 && "Unknown unary op!");
214 case tok::plusplus: Opc = UnaryOperator::PostInc; break;
215 case tok::minusminus: Opc = UnaryOperator::PostDec; break;
216 }
217
218 return new UnaryOperator((Expr*)Input, Opc);
219}
220
221Action::ExprResult Sema::
222ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
223 ExprTy *Idx, SourceLocation RLoc) {
Steve Narofff1e53692007-03-23 22:27:02 +0000224 TypeRef t1 = ((Expr *)Base)->getTypeRef();
225 TypeRef t2 = ((Expr *)Idx)->getTypeRef();
226
227 assert(!t1.isNull() && "no type for array base expression");
228 assert(!t1.isNull() && "no type for array index expression");
229
230 // In C, the expression e1[e2] is by definition precisely equivalent to
231 // the expression *((e1)+(e2)). This means the array "Base" may actually be
232 // in the subscript position. As a result, we need to derive the array base
233 // and index from the expression types.
234
235 TypeRef baseType, indexType;
236 if (isa<ArrayType>(t1) || isa<PointerType>(t1)) {
237 baseType = t1;
238 indexType = t2;
239 } else if (isa<ArrayType>(t2) || isa<PointerType>(t2)) { // uncommon case
240 baseType = t2;
241 indexType = t1;
242 } else
243 return Diag(LLoc, diag::err_typecheck_subscript_value);
244
245 if (indexType->isIntegralType())
246 return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, baseType);
247 else
248 return Diag(LLoc, diag::err_typecheck_subscript);
Chris Lattnere168f762006-11-10 05:29:30 +0000249}
250
251Action::ExprResult Sema::
252ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
253 tok::TokenKind OpKind, SourceLocation MemberLoc,
254 IdentifierInfo &Member) {
Steve Narofff1e53692007-03-23 22:27:02 +0000255 TypeRef BT = ((Expr *)Base)->getTypeRef();
256
257 assert(!BT.isNull() && "no type for member expression");
258
259 if (OpKind == tok::arrow) {
260 if (PointerType *PT = dyn_cast<PointerType>(BT))
261 BT = PT->getPointeeType();
262 else
263 return Diag(OpLoc, diag::err_typecheck_member_reference_arrow);
264 }
Steve Naroffcc321422007-03-26 23:09:51 +0000265 if (isa<RecordType>(BT)) { // get the struct/union definition from the type.
266 RecordDecl *RD = cast<RecordType>(BT)->getDecl();
267
Steve Narofff1e53692007-03-23 22:27:02 +0000268 if (BT->isIncompleteType())
Steve Naroffcc321422007-03-26 23:09:51 +0000269 return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RD->getName());
270
271 if (FieldDecl *MemberDecl = RD->getMember(&Member))
272 return new MemberExpr((Expr*)Base, OpKind == tok::arrow, MemberDecl);
273 else
274 return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName());
275 }
276 return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion);
Chris Lattnere168f762006-11-10 05:29:30 +0000277}
278
279/// ParseCallExpr - Handle a call to Fn with the specified array of arguments.
280/// This provides the location of the left/right parens and a list of comma
281/// locations.
282Action::ExprResult Sema::
283ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
284 ExprTy **Args, unsigned NumArgs,
285 SourceLocation *CommaLocs, SourceLocation RParenLoc) {
286 return new CallExpr((Expr*)Fn, (Expr**)Args, NumArgs);
287}
288
289Action::ExprResult Sema::
290ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
291 SourceLocation RParenLoc, ExprTy *Op) {
Chris Lattner0d8b1a12006-11-20 04:34:45 +0000292 // If error parsing type, ignore.
293 if (Ty == 0) return true;
294 return new CastExpr(TypeRef::getFromOpaquePtr(Ty), (Expr*)Op);
Chris Lattnere168f762006-11-10 05:29:30 +0000295}
296
297
298
299// Binary Operators. 'Tok' is the token for the operator.
300Action::ExprResult Sema::ParseBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
301 ExprTy *LHS, ExprTy *RHS) {
302 BinaryOperator::Opcode Opc;
303 switch (Kind) {
304 default: assert(0 && "Unknown binop!");
305 case tok::star: Opc = BinaryOperator::Mul; break;
306 case tok::slash: Opc = BinaryOperator::Div; break;
307 case tok::percent: Opc = BinaryOperator::Rem; break;
308 case tok::plus: Opc = BinaryOperator::Add; break;
309 case tok::minus: Opc = BinaryOperator::Sub; break;
310 case tok::lessless: Opc = BinaryOperator::Shl; break;
311 case tok::greatergreater: Opc = BinaryOperator::Shr; break;
312 case tok::lessequal: Opc = BinaryOperator::LE; break;
313 case tok::less: Opc = BinaryOperator::LT; break;
314 case tok::greaterequal: Opc = BinaryOperator::GE; break;
315 case tok::greater: Opc = BinaryOperator::GT; break;
316 case tok::exclaimequal: Opc = BinaryOperator::NE; break;
317 case tok::equalequal: Opc = BinaryOperator::EQ; break;
318 case tok::amp: Opc = BinaryOperator::And; break;
319 case tok::caret: Opc = BinaryOperator::Xor; break;
320 case tok::pipe: Opc = BinaryOperator::Or; break;
321 case tok::ampamp: Opc = BinaryOperator::LAnd; break;
322 case tok::pipepipe: Opc = BinaryOperator::LOr; break;
323 case tok::equal: Opc = BinaryOperator::Assign; break;
324 case tok::starequal: Opc = BinaryOperator::MulAssign; break;
325 case tok::slashequal: Opc = BinaryOperator::DivAssign; break;
326 case tok::percentequal: Opc = BinaryOperator::RemAssign; break;
327 case tok::plusequal: Opc = BinaryOperator::AddAssign; break;
328 case tok::minusequal: Opc = BinaryOperator::SubAssign; break;
329 case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break;
330 case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break;
331 case tok::ampequal: Opc = BinaryOperator::AndAssign; break;
332 case tok::caretequal: Opc = BinaryOperator::XorAssign; break;
333 case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
334 case tok::comma: Opc = BinaryOperator::Comma; break;
335 }
Steve Narofff1e53692007-03-23 22:27:02 +0000336
337 // perform implicit conversions (C99 6.3)
338 Expr *e1 = ImplicitConversion((Expr*)LHS);
339 Expr *e2 = ImplicitConversion((Expr*)RHS);
Chris Lattnere168f762006-11-10 05:29:30 +0000340
Steve Naroff26c8ea52007-03-21 21:08:52 +0000341 if (BinaryOperator::isMultiplicativeOp(Opc))
342 CheckMultiplicativeOperands((Expr*)LHS, (Expr*)RHS);
343 else if (BinaryOperator::isAdditiveOp(Opc))
344 CheckAdditiveOperands((Expr*)LHS, (Expr*)RHS);
345 else if (BinaryOperator::isShiftOp(Opc))
346 CheckShiftOperands((Expr*)LHS, (Expr*)RHS);
347 else if (BinaryOperator::isRelationalOp(Opc))
348 CheckRelationalOperands((Expr*)LHS, (Expr*)RHS);
349 else if (BinaryOperator::isEqualityOp(Opc))
350 CheckEqualityOperands((Expr*)LHS, (Expr*)RHS);
351 else if (BinaryOperator::isBitwiseOp(Opc))
352 CheckBitwiseOperands((Expr*)LHS, (Expr*)RHS);
353 else if (BinaryOperator::isLogicalOp(Opc))
354 CheckLogicalOperands((Expr*)LHS, (Expr*)RHS);
355
Chris Lattnere168f762006-11-10 05:29:30 +0000356 return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
357}
358
359/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
360/// in the case of a the GNU conditional expr extension.
361Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc,
362 SourceLocation ColonLoc,
363 ExprTy *Cond, ExprTy *LHS,
364 ExprTy *RHS) {
365 return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
366}
367
Steve Narofff1e53692007-03-23 22:27:02 +0000368Expr *Sema::ImplicitConversion(Expr *E) {
369#if 0
370 TypeRef t = E->getTypeRef();
371 if (t != 0) t.dump();
372 else printf("no type for expr %s\n", E->getStmtClassName());
373#endif
374 return E;
375}
376
Steve Naroff26c8ea52007-03-21 21:08:52 +0000377void Sema::CheckMultiplicativeOperands(Expr *op1, Expr *op2) {
378}
379
380void Sema::CheckAdditiveOperands(Expr *op1, Expr *op2) {
381}
382
383void Sema::CheckShiftOperands(Expr *op1, Expr *op2) {
384}
385
386void Sema::CheckRelationalOperands(Expr *op1, Expr *op2) {
387}
388
389void Sema::CheckEqualityOperands(Expr *op1, Expr *op2) {
390}
391
392void Sema::CheckBitwiseOperands(Expr *op1, Expr *op2) {
393}
394
395void Sema::CheckLogicalOperands(Expr *op1, Expr *op2) {
396}
397