blob: 95b2a295236a6b15218df5e59b22e8739af2c218 [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 Gregoraa6af222009-03-25 00:27:28 +000050 OwningExprResult VisitBinaryOperator(BinaryOperator *E);
51 OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
Douglas Gregor4a2e2042009-05-15 21:45:53 +000052 OwningExprResult VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000053 OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
54 OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
55 OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
56 OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
57 OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
Anders Carlsson0712d292009-05-15 20:26:03 +000058 OwningExprResult VisitCXXThisExpr(CXXThisExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000059 OwningExprResult VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
60 OwningExprResult VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
61 OwningExprResult VisitGNUNullExpr(GNUNullExpr *E);
Douglas Gregor4a2487a2009-05-19 00:38:01 +000062 OwningExprResult VisitUnresolvedFunctionNameExpr(
63 UnresolvedFunctionNameExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000064
Douglas Gregoraa6af222009-03-25 00:27:28 +000065 // Base case. I'm supposed to ignore this.
66 Sema::OwningExprResult VisitStmt(Stmt *S) {
67 S->dump();
68 assert(false && "Cannot instantiate this kind of expression");
69 return SemaRef.ExprError();
70 }
71 };
72}
73
Sebastian Redl8b0b4752009-05-16 18:50:46 +000074Sema::OwningExprResult
75TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) {
76 return SemaRef.Clone(E);
77}
78
79Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +000080TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
81 return SemaRef.Clone(E);
82}
83
84Sema::OwningExprResult
Sebastian Redl8b0b4752009-05-16 18:50:46 +000085TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) {
86 return SemaRef.Clone(E);
87}
88
89Sema::OwningExprResult
90TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) {
91 return SemaRef.Clone(E);
92}
93
94Sema::OwningExprResult
95TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) {
96 return SemaRef.Clone(E);
97}
98
Douglas Gregord8ac4362009-05-18 22:38:38 +000099Sema::OwningExprResult
100TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
101 return SemaRef.Clone(E);
102}
103
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000104Sema::OwningExprResult
105TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
106 return SemaRef.Clone(E);
107}
108
109Sema::OwningExprResult
110TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
111 return SemaRef.Clone(E);
112}
113
114Sema::OwningExprResult
115TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) {
116 return SemaRef.Clone(E);
117}
118
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000119Sema::OwningExprResult
120TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
121 UnresolvedFunctionNameExpr *E) {
122 return SemaRef.Clone(E);
123}
124
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000125Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000126TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
127 Decl *D = E->getDecl();
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000128 ValueDecl *NewD = 0;
Douglas Gregoraa6af222009-03-25 00:27:28 +0000129 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
130 assert(NTTP->getDepth() == 0 && "No nested templates yet");
131 const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
132 QualType T = Arg.getIntegralType();
133 if (T->isCharType() || T->isWideCharType())
134 return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
135 Arg.getAsIntegral()->getZExtValue(),
136 T->isWideCharType(),
137 T,
138 E->getSourceRange().getBegin()));
139 else if (T->isBooleanType())
140 return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
141 Arg.getAsIntegral()->getBoolValue(),
142 T,
143 E->getSourceRange().getBegin()));
144
145 return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
146 *Arg.getAsIntegral(),
147 T,
148 E->getSourceRange().getBegin()));
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000149 } else if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D))
150 NewD = SemaRef.CurrentInstantiationScope->getInstantiationOf(Parm);
151 else if (isa<FunctionDecl>(D) || isa<OverloadedFunctionDecl>(D))
152 // FIXME: Instantiate decl!
153 NewD = cast<ValueDecl>(D);
154 else
155 assert(false && "Unhandled declaratrion reference kind");
156
157 if (!NewD)
158 return SemaRef.ExprError();
159
160 QualType T = NewD->getType();
161 return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
Douglas Gregor48dd19b2009-05-14 21:44:34 +0000162 T.getNonReferenceType(),
163 E->getLocation(),
164 T->isDependentType(),
165 T->isDependentType()));
Douglas Gregoraa6af222009-03-25 00:27:28 +0000166}
167
168Sema::OwningExprResult
169TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
170 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
171 if (SubExpr.isInvalid())
172 return SemaRef.ExprError();
173
174 return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
175 E->getLParen(), E->getRParen(),
176 (Expr *)SubExpr.release()));
177}
178
179Sema::OwningExprResult
180TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
181 Sema::OwningExprResult Arg = Visit(E->getSubExpr());
182 if (Arg.isInvalid())
183 return SemaRef.ExprError();
184
185 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
186 E->getOpcode(),
187 move(Arg));
188}
189
190Sema::OwningExprResult
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000191TemplateExprInstantiator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
192 Sema::OwningExprResult LHS = Visit(E->getLHS());
193 if (LHS.isInvalid())
194 return SemaRef.ExprError();
195
196 Sema::OwningExprResult RHS = Visit(E->getRHS());
197 if (RHS.isInvalid())
198 return SemaRef.ExprError();
199
200 // Since the overloaded array-subscript operator (operator[]) can
201 // only be a member function, we can make several simplifying
202 // assumptions here:
203 // 1) Normal name lookup (from the current scope) will not ever
204 // find any declarations of operator[] that won't also be found be
205 // member operator lookup, so it is safe to pass a NULL Scope
206 // during the instantiation to avoid the lookup entirely.
207 //
208 // 2) Neither normal name lookup nor argument-dependent lookup at
209 // template definition time will find any operators that won't be
210 // found at template instantiation time, so we do not need to
211 // cache the results of name lookup as we do for the binary
212 // operators.
213 SourceLocation LLocFake = ((Expr*)LHS.get())->getSourceRange().getBegin();
214 return SemaRef.ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
215 /*FIXME:*/LLocFake,
216 move(RHS),
217 E->getRBracketLoc());
218}
219
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000220Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) {
221 // Instantiate callee
222 OwningExprResult Callee = Visit(E->getCallee());
223 if (Callee.isInvalid())
224 return SemaRef.ExprError();
225
226 // Instantiate arguments
227 llvm::SmallVector<Expr*, 8> Args;
228 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
229 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
230 OwningExprResult Arg = Visit(E->getArg(I));
231 if (Arg.isInvalid()) {
232 for (unsigned Victim = 0; Victim != I; ++Victim)
233 Args[Victim]->Destroy(SemaRef.Context);
234 return SemaRef.ExprError();
235 }
236
237 FakeCommaLocs.push_back(
238 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
239 Args.push_back(Arg.takeAs<Expr>());
240 }
241
242 SourceLocation FakeLParenLoc
243 = ((Expr *)Callee.get())->getSourceRange().getBegin();
244 return SemaRef.ActOnCallExpr(/*Scope=*/0, move(Callee),
245 /*FIXME:*/FakeLParenLoc,
246 Sema::MultiExprArg(SemaRef,
247 (void **)&Args.front(),
248 Args.size()),
249 /*FIXME:*/&FakeCommaLocs.front(),
250 E->getRParenLoc());
251}
252
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000253Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000254TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
255 Sema::OwningExprResult LHS = Visit(E->getLHS());
256 if (LHS.isInvalid())
257 return SemaRef.ExprError();
258
259 Sema::OwningExprResult RHS = Visit(E->getRHS());
260 if (RHS.isInvalid())
261 return SemaRef.ExprError();
262
263 Sema::OwningExprResult Result
264 = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
265 E->getOpcode(),
266 (Expr *)LHS.get(),
267 (Expr *)RHS.get());
268 if (Result.isInvalid())
269 return SemaRef.ExprError();
270
271 LHS.release();
272 RHS.release();
273 return move(Result);
274}
275
276Sema::OwningExprResult
277TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
278 Sema::OwningExprResult First = Visit(E->getArg(0));
279 if (First.isInvalid())
280 return SemaRef.ExprError();
281
282 Expr *Args[2] = { (Expr *)First.get(), 0 };
283
284 Sema::OwningExprResult Second(SemaRef);
285 if (E->getNumArgs() == 2) {
286 Second = Visit(E->getArg(1));
287
288 if (Second.isInvalid())
289 return SemaRef.ExprError();
290
291 Args[1] = (Expr *)Second.get();
292 }
293
294 if (!E->isTypeDependent()) {
295 // Since our original expression was not type-dependent, we do not
296 // perform lookup again at instantiation time (C++ [temp.dep]p1).
297 // Instead, we just build the new overloaded operator call
298 // expression.
299 First.release();
300 Second.release();
301 // FIXME: Don't reuse the callee here. We need to instantiate it.
302 return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
303 SemaRef.Context,
304 E->getOperator(),
305 E->getCallee(),
306 Args, E->getNumArgs(),
307 E->getType(),
308 E->getOperatorLoc()));
309 }
310
311 bool isPostIncDec = E->getNumArgs() == 2 &&
312 (E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
313 if (E->getNumArgs() == 1 || isPostIncDec) {
314 if (!Args[0]->getType()->isOverloadableType()) {
315 // The argument is not of overloadable type, so try to create a
316 // built-in unary operation.
317 UnaryOperator::Opcode Opc
318 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
319
320 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
321 move(First));
322 }
323
324 // Fall through to perform overload resolution
325 } else {
326 assert(E->getNumArgs() == 2 && "Expected binary operation");
327
328 Sema::OwningExprResult Result(SemaRef);
329 if (!Args[0]->getType()->isOverloadableType() &&
330 !Args[1]->getType()->isOverloadableType()) {
331 // Neither of the arguments is an overloadable type, so try to
332 // create a built-in binary operation.
333 BinaryOperator::Opcode Opc =
334 BinaryOperator::getOverloadedOpcode(E->getOperator());
335 Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
336 Args[0], Args[1]);
337 if (Result.isInvalid())
338 return SemaRef.ExprError();
339
340 First.release();
341 Second.release();
342 return move(Result);
343 }
344
345 // Fall through to perform overload resolution.
346 }
347
348 // Compute the set of functions that were found at template
349 // definition time.
350 Sema::FunctionSet Functions;
351 DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
352 OverloadedFunctionDecl *Overloads
353 = cast<OverloadedFunctionDecl>(DRE->getDecl());
354
355 // FIXME: Do we have to check
356 // IsAcceptableNonMemberOperatorCandidate for each of these?
357 for (OverloadedFunctionDecl::function_iterator
358 F = Overloads->function_begin(),
359 FEnd = Overloads->function_end();
360 F != FEnd; ++F)
361 Functions.insert(*F);
362
363 // Add any functions found via argument-dependent lookup.
364 DeclarationName OpName
365 = SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
366 SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
367
368 // Create the overloaded operator invocation.
369 if (E->getNumArgs() == 1 || isPostIncDec) {
370 UnaryOperator::Opcode Opc
371 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
372 return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
373 Functions, move(First));
374 }
375
Mike Stump390b4cc2009-05-16 07:39:55 +0000376 // FIXME: This would be far less ugly if CreateOverloadedBinOp took in ExprArg
377 // arguments!
Douglas Gregoraa6af222009-03-25 00:27:28 +0000378 BinaryOperator::Opcode Opc =
379 BinaryOperator::getOverloadedOpcode(E->getOperator());
380 OwningExprResult Result
381 = SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
382 Functions, Args[0], Args[1]);
383
384 if (Result.isInvalid())
385 return SemaRef.ExprError();
386
387 First.release();
388 Second.release();
389 return move(Result);
390}
391
Douglas Gregor4a2e2042009-05-15 21:45:53 +0000392Sema::OwningExprResult
393TemplateExprInstantiator::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
394 VarDecl *Var
395 = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
396 SemaRef.CurContext,
397 TemplateArgs));
398 if (!Var)
399 return SemaRef.ExprError();
400
401 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(
402 E->getStartLoc(),
403 SourceLocation(),
404 Var));
405}
406
Douglas Gregoraa6af222009-03-25 00:27:28 +0000407Sema::OwningExprResult
408TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
409 Sema::OwningExprResult Cond = Visit(E->getCond());
410 if (Cond.isInvalid())
411 return SemaRef.ExprError();
412
413 // FIXME: use getLHS() and cope with NULLness
414 Sema::OwningExprResult True = Visit(E->getTrueExpr());
415 if (True.isInvalid())
416 return SemaRef.ExprError();
417
418 Sema::OwningExprResult False = Visit(E->getFalseExpr());
419 if (False.isInvalid())
420 return SemaRef.ExprError();
421
422 if (!E->isTypeDependent()) {
423 // Since our original expression was not type-dependent, we do not
424 // perform lookup again at instantiation time (C++ [temp.dep]p1).
425 // Instead, we just build the new conditional operator call expression.
426 return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
427 Cond.takeAs<Expr>(),
428 True.takeAs<Expr>(),
429 False.takeAs<Expr>(),
430 E->getType()));
431 }
432
433
434 return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
435 /*FIXME*/E->getFalseExpr()->getLocStart(),
436 move(Cond), move(True), move(False));
437}
438
439Sema::OwningExprResult
440TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
441 bool isSizeOf = E->isSizeOf();
442
443 if (E->isArgumentType()) {
444 QualType T = E->getArgumentType();
445 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000446 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000447 /*FIXME*/E->getOperatorLoc(),
448 &SemaRef.PP.getIdentifierTable().get("sizeof"));
449 if (T.isNull())
450 return SemaRef.ExprError();
451 }
452
453 return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
454 E->getSourceRange());
455 }
456
457 Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
458 if (Arg.isInvalid())
459 return SemaRef.ExprError();
460
461 Sema::OwningExprResult Result
462 = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
463 isSizeOf, E->getSourceRange());
464 if (Result.isInvalid())
465 return SemaRef.ExprError();
466
467 Arg.release();
468 return move(Result);
469}
470
471Sema::OwningExprResult
472TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
Douglas Gregorab452ba2009-03-26 23:50:42 +0000473 NestedNameSpecifier *NNS
474 = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
475 E->getQualifierRange(),
Douglas Gregor7e063902009-05-11 23:53:27 +0000476 TemplateArgs);
Douglas Gregorab452ba2009-03-26 23:50:42 +0000477 if (!NNS)
Douglas Gregoraa6af222009-03-25 00:27:28 +0000478 return SemaRef.ExprError();
479
Douglas Gregorab452ba2009-03-26 23:50:42 +0000480 CXXScopeSpec SS;
481 SS.setRange(E->getQualifierRange());
482 SS.setScopeRep(NNS);
483
Douglas Gregoraa6af222009-03-25 00:27:28 +0000484 // FIXME: We're passing in a NULL scope, because
485 // ActOnDeclarationNameExpr doesn't actually use the scope when we
486 // give it a non-empty scope specifier. Investigate whether it would
487 // be better to refactor ActOnDeclarationNameExpr.
488 return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
489 E->getDeclName(),
490 /*HasTrailingLParen=*/false,
491 &SS,
492 /*FIXME:isAddressOfOperand=*/false);
493}
494
495Sema::OwningExprResult
496TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
497 CXXTemporaryObjectExpr *E) {
498 QualType T = E->getType();
499 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000500 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000501 E->getTypeBeginLoc(), DeclarationName());
502 if (T.isNull())
503 return SemaRef.ExprError();
504 }
505
506 llvm::SmallVector<Expr *, 16> Args;
507 Args.reserve(E->getNumArgs());
508 bool Invalid = false;
509 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
510 ArgEnd = E->arg_end();
511 Arg != ArgEnd; ++Arg) {
512 OwningExprResult InstantiatedArg = Visit(*Arg);
513 if (InstantiatedArg.isInvalid()) {
514 Invalid = true;
515 break;
516 }
517
518 Args.push_back((Expr *)InstantiatedArg.release());
519 }
520
521 if (!Invalid) {
522 SourceLocation CommaLoc;
523 // FIXME: HACK!
524 if (Args.size() > 1)
525 CommaLoc
526 = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd());
527 Sema::OwningExprResult Result(
528 SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
529 /*, FIXME*/),
530 T.getAsOpaquePtr(),
531 /*FIXME*/E->getTypeBeginLoc(),
532 Sema::MultiExprArg(SemaRef,
533 (void**)&Args[0],
534 Args.size()),
535 /*HACK*/&CommaLoc,
536 E->getSourceRange().getEnd()));
537 // At this point, Args no longer owns the arguments, no matter what.
538 return move(Result);
539 }
540
541 // Clean up the instantiated arguments.
542 // FIXME: Would rather do this with RAII.
543 for (unsigned Idx = 0; Idx < Args.size(); ++Idx)
544 SemaRef.DeleteExpr(Args[Idx]);
545
546 return SemaRef.ExprError();
547}
548
549Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
550 ImplicitCastExpr *E) {
551 assert(!E->isTypeDependent() && "Implicit casts must have known types");
552
553 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
554 if (SubExpr.isInvalid())
555 return SemaRef.ExprError();
556
557 ImplicitCastExpr *ICE =
558 new (SemaRef.Context) ImplicitCastExpr(E->getType(),
559 (Expr *)SubExpr.release(),
560 E->isLvalueCast());
561 return SemaRef.Owned(ICE);
562}
563
Anders Carlsson0712d292009-05-15 20:26:03 +0000564Sema::OwningExprResult
565TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
566 QualType ThisType =
567 cast<CXXMethodDecl>(SemaRef.CurContext)->getThisType(SemaRef.Context);
568
569 CXXThisExpr *TE =
570 new (SemaRef.Context) CXXThisExpr(E->getLocStart(), ThisType);
571
572 return SemaRef.Owned(TE);
573}
574
Douglas Gregoraa6af222009-03-25 00:27:28 +0000575Sema::OwningExprResult
Douglas Gregor7e063902009-05-11 23:53:27 +0000576Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
Douglas Gregor50557a72009-05-15 20:47:12 +0000577 if (!E)
578 return Owned((Expr *)0);
579
Douglas Gregor7e063902009-05-11 23:53:27 +0000580 TemplateExprInstantiator Instantiator(*this, TemplateArgs);
Douglas Gregoraa6af222009-03-25 00:27:28 +0000581 return Instantiator.Visit(E);
582}