blob: 2589e301e0d1c69ae923001acf898c41ae9add20 [file] [log] [blame]
Douglas Gregorb70ccad2009-05-15 18:22:25 +00001//===--- SemaTemplateInstantiateExpr.cpp - C++ Template Expr Instantiation ===/
Douglas Gregoraa6af222009-03-25 00:27:28 +00002//
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//
Douglas Gregorb70ccad2009-05-15 18:22:25 +00009// This file implements C++ template instantiation for expressions.
Douglas Gregoraa6af222009-03-25 00:27:28 +000010//
11//===----------------------------------------------------------------------===/
12#include "Sema.h"
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/AST/StmtVisitor.h"
16#include "clang/AST/Expr.h"
17#include "clang/AST/ExprCXX.h"
18#include "clang/Parse/DeclSpec.h"
19#include "clang/Lex/Preprocessor.h" // for the identifier table
20#include "llvm/Support/Compiler.h"
21using namespace clang;
22
23namespace {
24 class VISIBILITY_HIDDEN TemplateExprInstantiator
25 : public StmtVisitor<TemplateExprInstantiator, Sema::OwningExprResult> {
26 Sema &SemaRef;
Douglas Gregor7e063902009-05-11 23:53:27 +000027 const TemplateArgumentList &TemplateArgs;
Douglas Gregoraa6af222009-03-25 00:27:28 +000028
29 public:
30 typedef Sema::OwningExprResult OwningExprResult;
31
32 TemplateExprInstantiator(Sema &SemaRef,
Douglas Gregor7e063902009-05-11 23:53:27 +000033 const TemplateArgumentList &TemplateArgs)
34 : SemaRef(SemaRef), TemplateArgs(TemplateArgs) { }
Douglas Gregoraa6af222009-03-25 00:27:28 +000035
Mike Stump390b4cc2009-05-16 07:39:55 +000036 // FIXME: Once we get closer to completion, replace these manually-written
37 // declarations with automatically-generated ones from
38 // clang/AST/StmtNodes.def.
Sebastian Redl8b0b4752009-05-16 18:50:46 +000039 OwningExprResult VisitPredefinedExpr(PredefinedExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000040 OwningExprResult VisitIntegerLiteral(IntegerLiteral *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000041 OwningExprResult VisitFloatingLiteral(FloatingLiteral *E);
42 OwningExprResult VisitStringLiteral(StringLiteral *E);
43 OwningExprResult VisitCharacterLiteral(CharacterLiteral *E);
Douglas Gregord8ac4362009-05-18 22:38:38 +000044 OwningExprResult VisitImaginaryLiteral(ImaginaryLiteral *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000045 OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
46 OwningExprResult VisitParenExpr(ParenExpr *E);
47 OwningExprResult VisitUnaryOperator(UnaryOperator *E);
Douglas Gregor3384c9c2009-05-19 00:01:19 +000048 OwningExprResult VisitArraySubscriptExpr(ArraySubscriptExpr *E);
Douglas Gregor4a2487a2009-05-19 00:38:01 +000049 OwningExprResult VisitCallExpr(CallExpr *E);
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000050 // FIXME: VisitMemberExpr
51 // FIXME: CompoundLiteralExpr
Douglas Gregoraa6af222009-03-25 00:27:28 +000052 OwningExprResult VisitBinaryOperator(BinaryOperator *E);
Douglas Gregor6731c312009-05-19 20:02:01 +000053 OwningExprResult VisitCompoundAssignOperator(CompoundAssignOperator *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000054 OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Douglas Gregor4a2e2042009-05-15 21:45:53 +000055 OwningExprResult VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000056 OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
57 OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
58 OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
59 OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000060 OwningExprResult VisitCastExpr(CastExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000061 OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000062 OwningExprResult VisitExplicitCastExpr(ExplicitCastExpr *E);
63 OwningExprResult VisitCStyleCastExpr(CStyleCastExpr *E);
64 OwningExprResult VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
65 OwningExprResult VisitCXXStaticCastExpr(CXXStaticCastExpr *E);
66 OwningExprResult VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E);
67 OwningExprResult VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
68 OwningExprResult VisitCXXConstCastExpr(CXXConstCastExpr *E);
Anders Carlsson0712d292009-05-15 20:26:03 +000069 OwningExprResult VisitCXXThisExpr(CXXThisExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000070 OwningExprResult VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
71 OwningExprResult VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
72 OwningExprResult VisitGNUNullExpr(GNUNullExpr *E);
Douglas Gregor4a2487a2009-05-19 00:38:01 +000073 OwningExprResult VisitUnresolvedFunctionNameExpr(
74 UnresolvedFunctionNameExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000075
Douglas Gregoraa6af222009-03-25 00:27:28 +000076 // Base case. I'm supposed to ignore this.
77 Sema::OwningExprResult VisitStmt(Stmt *S) {
78 S->dump();
79 assert(false && "Cannot instantiate this kind of expression");
80 return SemaRef.ExprError();
81 }
82 };
83}
84
Sebastian Redl8b0b4752009-05-16 18:50:46 +000085Sema::OwningExprResult
86TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) {
87 return SemaRef.Clone(E);
88}
89
90Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +000091TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
92 return SemaRef.Clone(E);
93}
94
95Sema::OwningExprResult
Sebastian Redl8b0b4752009-05-16 18:50:46 +000096TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) {
97 return SemaRef.Clone(E);
98}
99
100Sema::OwningExprResult
101TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) {
102 return SemaRef.Clone(E);
103}
104
105Sema::OwningExprResult
106TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) {
107 return SemaRef.Clone(E);
108}
109
Douglas Gregord8ac4362009-05-18 22:38:38 +0000110Sema::OwningExprResult
111TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
112 return SemaRef.Clone(E);
113}
114
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000115Sema::OwningExprResult
116TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
117 return SemaRef.Clone(E);
118}
119
120Sema::OwningExprResult
121TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
122 return SemaRef.Clone(E);
123}
124
125Sema::OwningExprResult
126TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) {
127 return SemaRef.Clone(E);
128}
129
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000130Sema::OwningExprResult
131TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
132 UnresolvedFunctionNameExpr *E) {
133 return SemaRef.Clone(E);
134}
135
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000136Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000137TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
138 Decl *D = E->getDecl();
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000139 ValueDecl *NewD = 0;
Douglas Gregoraa6af222009-03-25 00:27:28 +0000140 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
141 assert(NTTP->getDepth() == 0 && "No nested templates yet");
142 const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
143 QualType T = Arg.getIntegralType();
144 if (T->isCharType() || T->isWideCharType())
145 return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
146 Arg.getAsIntegral()->getZExtValue(),
147 T->isWideCharType(),
148 T,
149 E->getSourceRange().getBegin()));
150 else if (T->isBooleanType())
151 return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
152 Arg.getAsIntegral()->getBoolValue(),
153 T,
154 E->getSourceRange().getBegin()));
155
156 return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
157 *Arg.getAsIntegral(),
158 T,
159 E->getSourceRange().getBegin()));
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000160 } else if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D))
161 NewD = SemaRef.CurrentInstantiationScope->getInstantiationOf(Parm);
162 else if (isa<FunctionDecl>(D) || isa<OverloadedFunctionDecl>(D))
163 // FIXME: Instantiate decl!
164 NewD = cast<ValueDecl>(D);
165 else
166 assert(false && "Unhandled declaratrion reference kind");
167
168 if (!NewD)
169 return SemaRef.ExprError();
170
171 QualType T = NewD->getType();
172 return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
Douglas Gregor48dd19b2009-05-14 21:44:34 +0000173 T.getNonReferenceType(),
174 E->getLocation(),
175 T->isDependentType(),
176 T->isDependentType()));
Douglas Gregoraa6af222009-03-25 00:27:28 +0000177}
178
179Sema::OwningExprResult
180TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
181 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
182 if (SubExpr.isInvalid())
183 return SemaRef.ExprError();
184
185 return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
186 E->getLParen(), E->getRParen(),
187 (Expr *)SubExpr.release()));
188}
189
190Sema::OwningExprResult
191TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
192 Sema::OwningExprResult Arg = Visit(E->getSubExpr());
193 if (Arg.isInvalid())
194 return SemaRef.ExprError();
195
196 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
197 E->getOpcode(),
198 move(Arg));
199}
200
201Sema::OwningExprResult
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000202TemplateExprInstantiator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
203 Sema::OwningExprResult LHS = Visit(E->getLHS());
204 if (LHS.isInvalid())
205 return SemaRef.ExprError();
206
207 Sema::OwningExprResult RHS = Visit(E->getRHS());
208 if (RHS.isInvalid())
209 return SemaRef.ExprError();
210
211 // Since the overloaded array-subscript operator (operator[]) can
212 // only be a member function, we can make several simplifying
213 // assumptions here:
214 // 1) Normal name lookup (from the current scope) will not ever
215 // find any declarations of operator[] that won't also be found be
216 // member operator lookup, so it is safe to pass a NULL Scope
217 // during the instantiation to avoid the lookup entirely.
218 //
219 // 2) Neither normal name lookup nor argument-dependent lookup at
220 // template definition time will find any operators that won't be
221 // found at template instantiation time, so we do not need to
222 // cache the results of name lookup as we do for the binary
223 // operators.
224 SourceLocation LLocFake = ((Expr*)LHS.get())->getSourceRange().getBegin();
225 return SemaRef.ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
226 /*FIXME:*/LLocFake,
227 move(RHS),
228 E->getRBracketLoc());
229}
230
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000231Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) {
232 // Instantiate callee
233 OwningExprResult Callee = Visit(E->getCallee());
234 if (Callee.isInvalid())
235 return SemaRef.ExprError();
236
237 // Instantiate arguments
238 llvm::SmallVector<Expr*, 8> Args;
239 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
240 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
241 OwningExprResult Arg = Visit(E->getArg(I));
242 if (Arg.isInvalid()) {
243 for (unsigned Victim = 0; Victim != I; ++Victim)
244 Args[Victim]->Destroy(SemaRef.Context);
245 return SemaRef.ExprError();
246 }
247
248 FakeCommaLocs.push_back(
249 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
250 Args.push_back(Arg.takeAs<Expr>());
251 }
252
253 SourceLocation FakeLParenLoc
254 = ((Expr *)Callee.get())->getSourceRange().getBegin();
255 return SemaRef.ActOnCallExpr(/*Scope=*/0, move(Callee),
256 /*FIXME:*/FakeLParenLoc,
257 Sema::MultiExprArg(SemaRef,
258 (void **)&Args.front(),
259 Args.size()),
260 /*FIXME:*/&FakeCommaLocs.front(),
261 E->getRParenLoc());
262}
263
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000264Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000265TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
266 Sema::OwningExprResult LHS = Visit(E->getLHS());
267 if (LHS.isInvalid())
268 return SemaRef.ExprError();
269
270 Sema::OwningExprResult RHS = Visit(E->getRHS());
271 if (RHS.isInvalid())
272 return SemaRef.ExprError();
273
274 Sema::OwningExprResult Result
275 = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
276 E->getOpcode(),
277 (Expr *)LHS.get(),
278 (Expr *)RHS.get());
279 if (Result.isInvalid())
280 return SemaRef.ExprError();
281
282 LHS.release();
283 RHS.release();
284 return move(Result);
285}
286
287Sema::OwningExprResult
Douglas Gregor6731c312009-05-19 20:02:01 +0000288TemplateExprInstantiator::VisitCompoundAssignOperator(
289 CompoundAssignOperator *E) {
290 return VisitBinaryOperator(E);
291}
292
293Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000294TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
295 Sema::OwningExprResult First = Visit(E->getArg(0));
296 if (First.isInvalid())
297 return SemaRef.ExprError();
298
299 Expr *Args[2] = { (Expr *)First.get(), 0 };
300
301 Sema::OwningExprResult Second(SemaRef);
302 if (E->getNumArgs() == 2) {
303 Second = Visit(E->getArg(1));
304
305 if (Second.isInvalid())
306 return SemaRef.ExprError();
307
308 Args[1] = (Expr *)Second.get();
309 }
310
311 if (!E->isTypeDependent()) {
312 // Since our original expression was not type-dependent, we do not
313 // perform lookup again at instantiation time (C++ [temp.dep]p1).
314 // Instead, we just build the new overloaded operator call
315 // expression.
316 First.release();
317 Second.release();
318 // FIXME: Don't reuse the callee here. We need to instantiate it.
319 return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
320 SemaRef.Context,
321 E->getOperator(),
322 E->getCallee(),
323 Args, E->getNumArgs(),
324 E->getType(),
325 E->getOperatorLoc()));
326 }
327
328 bool isPostIncDec = E->getNumArgs() == 2 &&
329 (E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
330 if (E->getNumArgs() == 1 || isPostIncDec) {
331 if (!Args[0]->getType()->isOverloadableType()) {
332 // The argument is not of overloadable type, so try to create a
333 // built-in unary operation.
334 UnaryOperator::Opcode Opc
335 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
336
337 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
338 move(First));
339 }
340
341 // Fall through to perform overload resolution
342 } else {
343 assert(E->getNumArgs() == 2 && "Expected binary operation");
344
345 Sema::OwningExprResult Result(SemaRef);
346 if (!Args[0]->getType()->isOverloadableType() &&
347 !Args[1]->getType()->isOverloadableType()) {
348 // Neither of the arguments is an overloadable type, so try to
349 // create a built-in binary operation.
350 BinaryOperator::Opcode Opc =
351 BinaryOperator::getOverloadedOpcode(E->getOperator());
352 Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
353 Args[0], Args[1]);
354 if (Result.isInvalid())
355 return SemaRef.ExprError();
356
357 First.release();
358 Second.release();
359 return move(Result);
360 }
361
362 // Fall through to perform overload resolution.
363 }
364
365 // Compute the set of functions that were found at template
366 // definition time.
367 Sema::FunctionSet Functions;
368 DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
369 OverloadedFunctionDecl *Overloads
370 = cast<OverloadedFunctionDecl>(DRE->getDecl());
371
372 // FIXME: Do we have to check
373 // IsAcceptableNonMemberOperatorCandidate for each of these?
374 for (OverloadedFunctionDecl::function_iterator
375 F = Overloads->function_begin(),
376 FEnd = Overloads->function_end();
377 F != FEnd; ++F)
378 Functions.insert(*F);
379
380 // Add any functions found via argument-dependent lookup.
381 DeclarationName OpName
382 = SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
383 SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
384
385 // Create the overloaded operator invocation.
386 if (E->getNumArgs() == 1 || isPostIncDec) {
387 UnaryOperator::Opcode Opc
388 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
389 return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
390 Functions, move(First));
391 }
392
Mike Stump390b4cc2009-05-16 07:39:55 +0000393 // FIXME: This would be far less ugly if CreateOverloadedBinOp took in ExprArg
394 // arguments!
Douglas Gregoraa6af222009-03-25 00:27:28 +0000395 BinaryOperator::Opcode Opc =
396 BinaryOperator::getOverloadedOpcode(E->getOperator());
397 OwningExprResult Result
398 = SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
399 Functions, Args[0], Args[1]);
400
401 if (Result.isInvalid())
402 return SemaRef.ExprError();
403
404 First.release();
405 Second.release();
406 return move(Result);
407}
408
Douglas Gregor4a2e2042009-05-15 21:45:53 +0000409Sema::OwningExprResult
410TemplateExprInstantiator::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
411 VarDecl *Var
412 = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
413 SemaRef.CurContext,
414 TemplateArgs));
415 if (!Var)
416 return SemaRef.ExprError();
417
418 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(
419 E->getStartLoc(),
420 SourceLocation(),
421 Var));
422}
423
Douglas Gregoraa6af222009-03-25 00:27:28 +0000424Sema::OwningExprResult
425TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
426 Sema::OwningExprResult Cond = Visit(E->getCond());
427 if (Cond.isInvalid())
428 return SemaRef.ExprError();
429
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000430 Sema::OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(),
431 TemplateArgs);
432 if (LHS.isInvalid())
Douglas Gregoraa6af222009-03-25 00:27:28 +0000433 return SemaRef.ExprError();
434
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000435 Sema::OwningExprResult RHS = Visit(E->getRHS());
436 if (RHS.isInvalid())
Douglas Gregoraa6af222009-03-25 00:27:28 +0000437 return SemaRef.ExprError();
438
439 if (!E->isTypeDependent()) {
440 // Since our original expression was not type-dependent, we do not
441 // perform lookup again at instantiation time (C++ [temp.dep]p1).
442 // Instead, we just build the new conditional operator call expression.
443 return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
444 Cond.takeAs<Expr>(),
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000445 LHS.takeAs<Expr>(),
446 RHS.takeAs<Expr>(),
Douglas Gregoraa6af222009-03-25 00:27:28 +0000447 E->getType()));
448 }
449
450
451 return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
452 /*FIXME*/E->getFalseExpr()->getLocStart(),
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000453 move(Cond), move(LHS), move(RHS));
Douglas Gregoraa6af222009-03-25 00:27:28 +0000454}
455
456Sema::OwningExprResult
457TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
458 bool isSizeOf = E->isSizeOf();
459
460 if (E->isArgumentType()) {
461 QualType T = E->getArgumentType();
462 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000463 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000464 /*FIXME*/E->getOperatorLoc(),
465 &SemaRef.PP.getIdentifierTable().get("sizeof"));
466 if (T.isNull())
467 return SemaRef.ExprError();
468 }
469
470 return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
471 E->getSourceRange());
472 }
473
474 Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
475 if (Arg.isInvalid())
476 return SemaRef.ExprError();
477
478 Sema::OwningExprResult Result
479 = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
480 isSizeOf, E->getSourceRange());
481 if (Result.isInvalid())
482 return SemaRef.ExprError();
483
484 Arg.release();
485 return move(Result);
486}
487
488Sema::OwningExprResult
489TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
Douglas Gregorab452ba2009-03-26 23:50:42 +0000490 NestedNameSpecifier *NNS
491 = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
492 E->getQualifierRange(),
Douglas Gregor7e063902009-05-11 23:53:27 +0000493 TemplateArgs);
Douglas Gregorab452ba2009-03-26 23:50:42 +0000494 if (!NNS)
Douglas Gregoraa6af222009-03-25 00:27:28 +0000495 return SemaRef.ExprError();
496
Douglas Gregorab452ba2009-03-26 23:50:42 +0000497 CXXScopeSpec SS;
498 SS.setRange(E->getQualifierRange());
499 SS.setScopeRep(NNS);
500
Douglas Gregoraa6af222009-03-25 00:27:28 +0000501 // FIXME: We're passing in a NULL scope, because
502 // ActOnDeclarationNameExpr doesn't actually use the scope when we
503 // give it a non-empty scope specifier. Investigate whether it would
504 // be better to refactor ActOnDeclarationNameExpr.
505 return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
506 E->getDeclName(),
507 /*HasTrailingLParen=*/false,
508 &SS,
509 /*FIXME:isAddressOfOperand=*/false);
510}
511
512Sema::OwningExprResult
513TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
514 CXXTemporaryObjectExpr *E) {
515 QualType T = E->getType();
516 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000517 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000518 E->getTypeBeginLoc(), DeclarationName());
519 if (T.isNull())
520 return SemaRef.ExprError();
521 }
522
523 llvm::SmallVector<Expr *, 16> Args;
524 Args.reserve(E->getNumArgs());
525 bool Invalid = false;
526 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
527 ArgEnd = E->arg_end();
528 Arg != ArgEnd; ++Arg) {
529 OwningExprResult InstantiatedArg = Visit(*Arg);
530 if (InstantiatedArg.isInvalid()) {
531 Invalid = true;
532 break;
533 }
534
535 Args.push_back((Expr *)InstantiatedArg.release());
536 }
537
538 if (!Invalid) {
539 SourceLocation CommaLoc;
540 // FIXME: HACK!
541 if (Args.size() > 1)
542 CommaLoc
543 = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd());
544 Sema::OwningExprResult Result(
545 SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
546 /*, FIXME*/),
547 T.getAsOpaquePtr(),
548 /*FIXME*/E->getTypeBeginLoc(),
549 Sema::MultiExprArg(SemaRef,
550 (void**)&Args[0],
551 Args.size()),
552 /*HACK*/&CommaLoc,
553 E->getSourceRange().getEnd()));
554 // At this point, Args no longer owns the arguments, no matter what.
555 return move(Result);
556 }
557
558 // Clean up the instantiated arguments.
559 // FIXME: Would rather do this with RAII.
560 for (unsigned Idx = 0; Idx < Args.size(); ++Idx)
561 SemaRef.DeleteExpr(Args[Idx]);
562
563 return SemaRef.ExprError();
564}
565
Douglas Gregora3a7b8e2009-05-19 19:05:47 +0000566Sema::OwningExprResult TemplateExprInstantiator::VisitCastExpr(CastExpr *E) {
567 assert(false && "Cannot instantiate abstract CastExpr");
568 return SemaRef.ExprError();
569}
570
Douglas Gregoraa6af222009-03-25 00:27:28 +0000571Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
572 ImplicitCastExpr *E) {
573 assert(!E->isTypeDependent() && "Implicit casts must have known types");
574
575 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
576 if (SubExpr.isInvalid())
577 return SemaRef.ExprError();
578
579 ImplicitCastExpr *ICE =
580 new (SemaRef.Context) ImplicitCastExpr(E->getType(),
581 (Expr *)SubExpr.release(),
582 E->isLvalueCast());
583 return SemaRef.Owned(ICE);
584}
585
Douglas Gregora3a7b8e2009-05-19 19:05:47 +0000586Sema::OwningExprResult
587TemplateExprInstantiator::VisitExplicitCastExpr(ExplicitCastExpr *E) {
588 assert(false && "Cannot instantiate abstract ExplicitCastExpr");
589 return SemaRef.ExprError();
590}
591
592Sema::OwningExprResult
593TemplateExprInstantiator::VisitCStyleCastExpr(CStyleCastExpr *E) {
594 // Instantiate the type that we're casting to.
595 SourceLocation TypeStartLoc
596 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
597 QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
598 TemplateArgs,
599 TypeStartLoc,
600 DeclarationName());
601 if (ExplicitTy.isNull())
602 return SemaRef.ExprError();
603
604 // Instantiate the subexpression.
605 OwningExprResult SubExpr = Visit(E->getSubExpr());
606 if (SubExpr.isInvalid())
607 return SemaRef.ExprError();
608
609 return SemaRef.ActOnCastExpr(E->getLParenLoc(),
610 ExplicitTy.getAsOpaquePtr(),
611 E->getRParenLoc(),
612 move(SubExpr));
613}
614
615Sema::OwningExprResult
616TemplateExprInstantiator::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
617 // Figure out which cast operator we're dealing with.
618 tok::TokenKind Kind;
619 switch (E->getStmtClass()) {
620 case Stmt::CXXStaticCastExprClass:
621 Kind = tok::kw_static_cast;
622 break;
623
624 case Stmt::CXXDynamicCastExprClass:
625 Kind = tok::kw_dynamic_cast;
626 break;
627
628 case Stmt::CXXReinterpretCastExprClass:
629 Kind = tok::kw_reinterpret_cast;
630 break;
631
632 case Stmt::CXXConstCastExprClass:
633 Kind = tok::kw_const_cast;
634 break;
635
636 default:
637 assert(false && "Invalid C++ named cast");
638 return SemaRef.ExprError();
639 }
640
641 // Instantiate the type that we're casting to.
642 SourceLocation TypeStartLoc
643 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
644 QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
645 TemplateArgs,
646 TypeStartLoc,
647 DeclarationName());
648 if (ExplicitTy.isNull())
649 return SemaRef.ExprError();
650
651 // Instantiate the subexpression.
652 OwningExprResult SubExpr = Visit(E->getSubExpr());
653 if (SubExpr.isInvalid())
654 return SemaRef.ExprError();
655
656 SourceLocation FakeLAngleLoc
657 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
658 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
659 SourceLocation FakeRParenLoc
660 = SemaRef.PP.getLocForEndOfToken(
661 E->getSubExpr()->getSourceRange().getEnd());
662 return SemaRef.ActOnCXXNamedCast(E->getOperatorLoc(), Kind,
663 /*FIXME:*/FakeLAngleLoc,
664 ExplicitTy.getAsOpaquePtr(),
665 /*FIXME:*/FakeRAngleLoc,
666 /*FIXME:*/FakeRAngleLoc,
667 move(SubExpr),
668 /*FIXME:*/FakeRParenLoc);
669}
670
671Sema::OwningExprResult
672TemplateExprInstantiator::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
673 return VisitCXXNamedCastExpr(E);
674}
675
676Sema::OwningExprResult
677TemplateExprInstantiator::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
678 return VisitCXXNamedCastExpr(E);
679}
680
681Sema::OwningExprResult
682TemplateExprInstantiator::VisitCXXReinterpretCastExpr(
683 CXXReinterpretCastExpr *E) {
684 return VisitCXXNamedCastExpr(E);
685}
686
687Sema::OwningExprResult
688TemplateExprInstantiator::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
689 return VisitCXXNamedCastExpr(E);
690}
691
Anders Carlsson0712d292009-05-15 20:26:03 +0000692Sema::OwningExprResult
693TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
694 QualType ThisType =
695 cast<CXXMethodDecl>(SemaRef.CurContext)->getThisType(SemaRef.Context);
696
697 CXXThisExpr *TE =
698 new (SemaRef.Context) CXXThisExpr(E->getLocStart(), ThisType);
699
700 return SemaRef.Owned(TE);
701}
702
Douglas Gregoraa6af222009-03-25 00:27:28 +0000703Sema::OwningExprResult
Douglas Gregor7e063902009-05-11 23:53:27 +0000704Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
Douglas Gregor50557a72009-05-15 20:47:12 +0000705 if (!E)
706 return Owned((Expr *)0);
707
Douglas Gregor7e063902009-05-11 23:53:27 +0000708 TemplateExprInstantiator Instantiator(*this, TemplateArgs);
Douglas Gregoraa6af222009-03-25 00:27:28 +0000709 return Instantiator.Visit(E);
710}