blob: 7cf403c282ad69dd8f23e4b68269904afc99c75f [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);
Douglas Gregorcd938172009-05-19 20:31:21 +000057 // FIXME: AddrLabelExpr
58 OwningExprResult VisitStmtExpr(StmtExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000059 OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
60 OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
61 OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000062 OwningExprResult VisitCastExpr(CastExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000063 OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000064 OwningExprResult VisitExplicitCastExpr(ExplicitCastExpr *E);
65 OwningExprResult VisitCStyleCastExpr(CStyleCastExpr *E);
66 OwningExprResult VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
67 OwningExprResult VisitCXXStaticCastExpr(CXXStaticCastExpr *E);
68 OwningExprResult VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E);
69 OwningExprResult VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
70 OwningExprResult VisitCXXConstCastExpr(CXXConstCastExpr *E);
Anders Carlsson0712d292009-05-15 20:26:03 +000071 OwningExprResult VisitCXXThisExpr(CXXThisExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000072 OwningExprResult VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
73 OwningExprResult VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
74 OwningExprResult VisitGNUNullExpr(GNUNullExpr *E);
Douglas Gregor4a2487a2009-05-19 00:38:01 +000075 OwningExprResult VisitUnresolvedFunctionNameExpr(
76 UnresolvedFunctionNameExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000077
Douglas Gregoraa6af222009-03-25 00:27:28 +000078 // Base case. I'm supposed to ignore this.
79 Sema::OwningExprResult VisitStmt(Stmt *S) {
80 S->dump();
81 assert(false && "Cannot instantiate this kind of expression");
82 return SemaRef.ExprError();
83 }
84 };
85}
86
Sebastian Redl8b0b4752009-05-16 18:50:46 +000087Sema::OwningExprResult
88TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) {
89 return SemaRef.Clone(E);
90}
91
92Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +000093TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
94 return SemaRef.Clone(E);
95}
96
97Sema::OwningExprResult
Sebastian Redl8b0b4752009-05-16 18:50:46 +000098TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) {
99 return SemaRef.Clone(E);
100}
101
102Sema::OwningExprResult
103TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) {
104 return SemaRef.Clone(E);
105}
106
107Sema::OwningExprResult
108TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) {
109 return SemaRef.Clone(E);
110}
111
Douglas Gregord8ac4362009-05-18 22:38:38 +0000112Sema::OwningExprResult
113TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
114 return SemaRef.Clone(E);
115}
116
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000117Sema::OwningExprResult
118TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
119 return SemaRef.Clone(E);
120}
121
122Sema::OwningExprResult
123TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
124 return SemaRef.Clone(E);
125}
126
127Sema::OwningExprResult
128TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) {
129 return SemaRef.Clone(E);
130}
131
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000132Sema::OwningExprResult
133TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
134 UnresolvedFunctionNameExpr *E) {
135 return SemaRef.Clone(E);
136}
137
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000138Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000139TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
140 Decl *D = E->getDecl();
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000141 ValueDecl *NewD = 0;
Douglas Gregoraa6af222009-03-25 00:27:28 +0000142 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
143 assert(NTTP->getDepth() == 0 && "No nested templates yet");
144 const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
145 QualType T = Arg.getIntegralType();
146 if (T->isCharType() || T->isWideCharType())
147 return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
148 Arg.getAsIntegral()->getZExtValue(),
149 T->isWideCharType(),
150 T,
151 E->getSourceRange().getBegin()));
152 else if (T->isBooleanType())
153 return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
154 Arg.getAsIntegral()->getBoolValue(),
155 T,
156 E->getSourceRange().getBegin()));
157
158 return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
159 *Arg.getAsIntegral(),
160 T,
161 E->getSourceRange().getBegin()));
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000162 } else if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D))
163 NewD = SemaRef.CurrentInstantiationScope->getInstantiationOf(Parm);
164 else if (isa<FunctionDecl>(D) || isa<OverloadedFunctionDecl>(D))
165 // FIXME: Instantiate decl!
166 NewD = cast<ValueDecl>(D);
167 else
168 assert(false && "Unhandled declaratrion reference kind");
169
170 if (!NewD)
171 return SemaRef.ExprError();
172
173 QualType T = NewD->getType();
174 return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
Douglas Gregor48dd19b2009-05-14 21:44:34 +0000175 T.getNonReferenceType(),
176 E->getLocation(),
177 T->isDependentType(),
178 T->isDependentType()));
Douglas Gregoraa6af222009-03-25 00:27:28 +0000179}
180
181Sema::OwningExprResult
182TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
183 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
184 if (SubExpr.isInvalid())
185 return SemaRef.ExprError();
186
187 return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
188 E->getLParen(), E->getRParen(),
189 (Expr *)SubExpr.release()));
190}
191
192Sema::OwningExprResult
193TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
194 Sema::OwningExprResult Arg = Visit(E->getSubExpr());
195 if (Arg.isInvalid())
196 return SemaRef.ExprError();
197
198 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
199 E->getOpcode(),
200 move(Arg));
201}
202
203Sema::OwningExprResult
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000204TemplateExprInstantiator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
205 Sema::OwningExprResult LHS = Visit(E->getLHS());
206 if (LHS.isInvalid())
207 return SemaRef.ExprError();
208
209 Sema::OwningExprResult RHS = Visit(E->getRHS());
210 if (RHS.isInvalid())
211 return SemaRef.ExprError();
212
213 // Since the overloaded array-subscript operator (operator[]) can
214 // only be a member function, we can make several simplifying
215 // assumptions here:
216 // 1) Normal name lookup (from the current scope) will not ever
217 // find any declarations of operator[] that won't also be found be
218 // member operator lookup, so it is safe to pass a NULL Scope
219 // during the instantiation to avoid the lookup entirely.
220 //
221 // 2) Neither normal name lookup nor argument-dependent lookup at
222 // template definition time will find any operators that won't be
223 // found at template instantiation time, so we do not need to
224 // cache the results of name lookup as we do for the binary
225 // operators.
226 SourceLocation LLocFake = ((Expr*)LHS.get())->getSourceRange().getBegin();
227 return SemaRef.ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
228 /*FIXME:*/LLocFake,
229 move(RHS),
230 E->getRBracketLoc());
231}
232
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000233Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) {
234 // Instantiate callee
235 OwningExprResult Callee = Visit(E->getCallee());
236 if (Callee.isInvalid())
237 return SemaRef.ExprError();
238
239 // Instantiate arguments
240 llvm::SmallVector<Expr*, 8> Args;
241 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
242 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
243 OwningExprResult Arg = Visit(E->getArg(I));
244 if (Arg.isInvalid()) {
245 for (unsigned Victim = 0; Victim != I; ++Victim)
246 Args[Victim]->Destroy(SemaRef.Context);
247 return SemaRef.ExprError();
248 }
249
250 FakeCommaLocs.push_back(
251 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
252 Args.push_back(Arg.takeAs<Expr>());
253 }
254
255 SourceLocation FakeLParenLoc
256 = ((Expr *)Callee.get())->getSourceRange().getBegin();
257 return SemaRef.ActOnCallExpr(/*Scope=*/0, move(Callee),
258 /*FIXME:*/FakeLParenLoc,
259 Sema::MultiExprArg(SemaRef,
260 (void **)&Args.front(),
261 Args.size()),
262 /*FIXME:*/&FakeCommaLocs.front(),
263 E->getRParenLoc());
264}
265
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000266Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000267TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
268 Sema::OwningExprResult LHS = Visit(E->getLHS());
269 if (LHS.isInvalid())
270 return SemaRef.ExprError();
271
272 Sema::OwningExprResult RHS = Visit(E->getRHS());
273 if (RHS.isInvalid())
274 return SemaRef.ExprError();
275
276 Sema::OwningExprResult Result
277 = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
278 E->getOpcode(),
279 (Expr *)LHS.get(),
280 (Expr *)RHS.get());
281 if (Result.isInvalid())
282 return SemaRef.ExprError();
283
284 LHS.release();
285 RHS.release();
286 return move(Result);
287}
288
289Sema::OwningExprResult
Douglas Gregor6731c312009-05-19 20:02:01 +0000290TemplateExprInstantiator::VisitCompoundAssignOperator(
291 CompoundAssignOperator *E) {
292 return VisitBinaryOperator(E);
293}
294
295Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000296TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
297 Sema::OwningExprResult First = Visit(E->getArg(0));
298 if (First.isInvalid())
299 return SemaRef.ExprError();
300
301 Expr *Args[2] = { (Expr *)First.get(), 0 };
302
303 Sema::OwningExprResult Second(SemaRef);
304 if (E->getNumArgs() == 2) {
305 Second = Visit(E->getArg(1));
306
307 if (Second.isInvalid())
308 return SemaRef.ExprError();
309
310 Args[1] = (Expr *)Second.get();
311 }
312
313 if (!E->isTypeDependent()) {
314 // Since our original expression was not type-dependent, we do not
315 // perform lookup again at instantiation time (C++ [temp.dep]p1).
316 // Instead, we just build the new overloaded operator call
317 // expression.
318 First.release();
319 Second.release();
320 // FIXME: Don't reuse the callee here. We need to instantiate it.
321 return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
322 SemaRef.Context,
323 E->getOperator(),
324 E->getCallee(),
325 Args, E->getNumArgs(),
326 E->getType(),
327 E->getOperatorLoc()));
328 }
329
330 bool isPostIncDec = E->getNumArgs() == 2 &&
331 (E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
332 if (E->getNumArgs() == 1 || isPostIncDec) {
333 if (!Args[0]->getType()->isOverloadableType()) {
334 // The argument is not of overloadable type, so try to create a
335 // built-in unary operation.
336 UnaryOperator::Opcode Opc
337 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
338
339 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
340 move(First));
341 }
342
343 // Fall through to perform overload resolution
344 } else {
345 assert(E->getNumArgs() == 2 && "Expected binary operation");
346
347 Sema::OwningExprResult Result(SemaRef);
348 if (!Args[0]->getType()->isOverloadableType() &&
349 !Args[1]->getType()->isOverloadableType()) {
350 // Neither of the arguments is an overloadable type, so try to
351 // create a built-in binary operation.
352 BinaryOperator::Opcode Opc =
353 BinaryOperator::getOverloadedOpcode(E->getOperator());
354 Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
355 Args[0], Args[1]);
356 if (Result.isInvalid())
357 return SemaRef.ExprError();
358
359 First.release();
360 Second.release();
361 return move(Result);
362 }
363
364 // Fall through to perform overload resolution.
365 }
366
367 // Compute the set of functions that were found at template
368 // definition time.
369 Sema::FunctionSet Functions;
370 DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
371 OverloadedFunctionDecl *Overloads
372 = cast<OverloadedFunctionDecl>(DRE->getDecl());
373
374 // FIXME: Do we have to check
375 // IsAcceptableNonMemberOperatorCandidate for each of these?
376 for (OverloadedFunctionDecl::function_iterator
377 F = Overloads->function_begin(),
378 FEnd = Overloads->function_end();
379 F != FEnd; ++F)
380 Functions.insert(*F);
381
382 // Add any functions found via argument-dependent lookup.
383 DeclarationName OpName
384 = SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
385 SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
386
387 // Create the overloaded operator invocation.
388 if (E->getNumArgs() == 1 || isPostIncDec) {
389 UnaryOperator::Opcode Opc
390 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
391 return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
392 Functions, move(First));
393 }
394
Mike Stump390b4cc2009-05-16 07:39:55 +0000395 // FIXME: This would be far less ugly if CreateOverloadedBinOp took in ExprArg
396 // arguments!
Douglas Gregoraa6af222009-03-25 00:27:28 +0000397 BinaryOperator::Opcode Opc =
398 BinaryOperator::getOverloadedOpcode(E->getOperator());
399 OwningExprResult Result
400 = SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
401 Functions, Args[0], Args[1]);
402
403 if (Result.isInvalid())
404 return SemaRef.ExprError();
405
406 First.release();
407 Second.release();
408 return move(Result);
409}
410
Douglas Gregor4a2e2042009-05-15 21:45:53 +0000411Sema::OwningExprResult
412TemplateExprInstantiator::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
413 VarDecl *Var
414 = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
415 SemaRef.CurContext,
416 TemplateArgs));
417 if (!Var)
418 return SemaRef.ExprError();
419
420 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(
421 E->getStartLoc(),
422 SourceLocation(),
423 Var));
424}
425
Douglas Gregoraa6af222009-03-25 00:27:28 +0000426Sema::OwningExprResult
427TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
428 Sema::OwningExprResult Cond = Visit(E->getCond());
429 if (Cond.isInvalid())
430 return SemaRef.ExprError();
431
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000432 Sema::OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(),
433 TemplateArgs);
434 if (LHS.isInvalid())
Douglas Gregoraa6af222009-03-25 00:27:28 +0000435 return SemaRef.ExprError();
436
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000437 Sema::OwningExprResult RHS = Visit(E->getRHS());
438 if (RHS.isInvalid())
Douglas Gregoraa6af222009-03-25 00:27:28 +0000439 return SemaRef.ExprError();
440
441 if (!E->isTypeDependent()) {
442 // Since our original expression was not type-dependent, we do not
443 // perform lookup again at instantiation time (C++ [temp.dep]p1).
444 // Instead, we just build the new conditional operator call expression.
445 return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
446 Cond.takeAs<Expr>(),
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000447 LHS.takeAs<Expr>(),
448 RHS.takeAs<Expr>(),
Douglas Gregoraa6af222009-03-25 00:27:28 +0000449 E->getType()));
450 }
451
452
453 return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
454 /*FIXME*/E->getFalseExpr()->getLocStart(),
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000455 move(Cond), move(LHS), move(RHS));
Douglas Gregoraa6af222009-03-25 00:27:28 +0000456}
457
Douglas Gregorcd938172009-05-19 20:31:21 +0000458Sema::OwningExprResult TemplateExprInstantiator::VisitStmtExpr(StmtExpr *E) {
459 Sema::OwningStmtResult SubStmt = SemaRef.InstantiateStmt(E->getSubStmt(),
460 TemplateArgs);
461 if (SubStmt.isInvalid())
462 return SemaRef.ExprError();
463
464 return SemaRef.ActOnStmtExpr(E->getLParenLoc(), move(SubStmt),
465 E->getRParenLoc());
466}
467
Douglas Gregoraa6af222009-03-25 00:27:28 +0000468Sema::OwningExprResult
469TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
470 bool isSizeOf = E->isSizeOf();
471
472 if (E->isArgumentType()) {
473 QualType T = E->getArgumentType();
474 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000475 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000476 /*FIXME*/E->getOperatorLoc(),
477 &SemaRef.PP.getIdentifierTable().get("sizeof"));
478 if (T.isNull())
479 return SemaRef.ExprError();
480 }
481
482 return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
483 E->getSourceRange());
484 }
485
486 Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
487 if (Arg.isInvalid())
488 return SemaRef.ExprError();
489
490 Sema::OwningExprResult Result
491 = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
492 isSizeOf, E->getSourceRange());
493 if (Result.isInvalid())
494 return SemaRef.ExprError();
495
496 Arg.release();
497 return move(Result);
498}
499
500Sema::OwningExprResult
501TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
Douglas Gregorab452ba2009-03-26 23:50:42 +0000502 NestedNameSpecifier *NNS
503 = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
504 E->getQualifierRange(),
Douglas Gregor7e063902009-05-11 23:53:27 +0000505 TemplateArgs);
Douglas Gregorab452ba2009-03-26 23:50:42 +0000506 if (!NNS)
Douglas Gregoraa6af222009-03-25 00:27:28 +0000507 return SemaRef.ExprError();
508
Douglas Gregorab452ba2009-03-26 23:50:42 +0000509 CXXScopeSpec SS;
510 SS.setRange(E->getQualifierRange());
511 SS.setScopeRep(NNS);
512
Douglas Gregoraa6af222009-03-25 00:27:28 +0000513 // FIXME: We're passing in a NULL scope, because
514 // ActOnDeclarationNameExpr doesn't actually use the scope when we
515 // give it a non-empty scope specifier. Investigate whether it would
516 // be better to refactor ActOnDeclarationNameExpr.
517 return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
518 E->getDeclName(),
519 /*HasTrailingLParen=*/false,
520 &SS,
521 /*FIXME:isAddressOfOperand=*/false);
522}
523
524Sema::OwningExprResult
525TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
526 CXXTemporaryObjectExpr *E) {
527 QualType T = E->getType();
528 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000529 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000530 E->getTypeBeginLoc(), DeclarationName());
531 if (T.isNull())
532 return SemaRef.ExprError();
533 }
534
535 llvm::SmallVector<Expr *, 16> Args;
536 Args.reserve(E->getNumArgs());
537 bool Invalid = false;
538 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
539 ArgEnd = E->arg_end();
540 Arg != ArgEnd; ++Arg) {
541 OwningExprResult InstantiatedArg = Visit(*Arg);
542 if (InstantiatedArg.isInvalid()) {
543 Invalid = true;
544 break;
545 }
546
547 Args.push_back((Expr *)InstantiatedArg.release());
548 }
549
550 if (!Invalid) {
551 SourceLocation CommaLoc;
552 // FIXME: HACK!
553 if (Args.size() > 1)
554 CommaLoc
555 = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd());
556 Sema::OwningExprResult Result(
557 SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
558 /*, FIXME*/),
559 T.getAsOpaquePtr(),
560 /*FIXME*/E->getTypeBeginLoc(),
561 Sema::MultiExprArg(SemaRef,
562 (void**)&Args[0],
563 Args.size()),
564 /*HACK*/&CommaLoc,
565 E->getSourceRange().getEnd()));
566 // At this point, Args no longer owns the arguments, no matter what.
567 return move(Result);
568 }
569
570 // Clean up the instantiated arguments.
571 // FIXME: Would rather do this with RAII.
572 for (unsigned Idx = 0; Idx < Args.size(); ++Idx)
573 SemaRef.DeleteExpr(Args[Idx]);
574
575 return SemaRef.ExprError();
576}
577
Douglas Gregora3a7b8e2009-05-19 19:05:47 +0000578Sema::OwningExprResult TemplateExprInstantiator::VisitCastExpr(CastExpr *E) {
579 assert(false && "Cannot instantiate abstract CastExpr");
580 return SemaRef.ExprError();
581}
582
Douglas Gregoraa6af222009-03-25 00:27:28 +0000583Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
584 ImplicitCastExpr *E) {
585 assert(!E->isTypeDependent() && "Implicit casts must have known types");
586
587 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
588 if (SubExpr.isInvalid())
589 return SemaRef.ExprError();
590
591 ImplicitCastExpr *ICE =
592 new (SemaRef.Context) ImplicitCastExpr(E->getType(),
593 (Expr *)SubExpr.release(),
594 E->isLvalueCast());
595 return SemaRef.Owned(ICE);
596}
597
Douglas Gregora3a7b8e2009-05-19 19:05:47 +0000598Sema::OwningExprResult
599TemplateExprInstantiator::VisitExplicitCastExpr(ExplicitCastExpr *E) {
600 assert(false && "Cannot instantiate abstract ExplicitCastExpr");
601 return SemaRef.ExprError();
602}
603
604Sema::OwningExprResult
605TemplateExprInstantiator::VisitCStyleCastExpr(CStyleCastExpr *E) {
606 // Instantiate the type that we're casting to.
607 SourceLocation TypeStartLoc
608 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
609 QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
610 TemplateArgs,
611 TypeStartLoc,
612 DeclarationName());
613 if (ExplicitTy.isNull())
614 return SemaRef.ExprError();
615
616 // Instantiate the subexpression.
617 OwningExprResult SubExpr = Visit(E->getSubExpr());
618 if (SubExpr.isInvalid())
619 return SemaRef.ExprError();
620
621 return SemaRef.ActOnCastExpr(E->getLParenLoc(),
622 ExplicitTy.getAsOpaquePtr(),
623 E->getRParenLoc(),
624 move(SubExpr));
625}
626
627Sema::OwningExprResult
628TemplateExprInstantiator::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
629 // Figure out which cast operator we're dealing with.
630 tok::TokenKind Kind;
631 switch (E->getStmtClass()) {
632 case Stmt::CXXStaticCastExprClass:
633 Kind = tok::kw_static_cast;
634 break;
635
636 case Stmt::CXXDynamicCastExprClass:
637 Kind = tok::kw_dynamic_cast;
638 break;
639
640 case Stmt::CXXReinterpretCastExprClass:
641 Kind = tok::kw_reinterpret_cast;
642 break;
643
644 case Stmt::CXXConstCastExprClass:
645 Kind = tok::kw_const_cast;
646 break;
647
648 default:
649 assert(false && "Invalid C++ named cast");
650 return SemaRef.ExprError();
651 }
652
653 // Instantiate the type that we're casting to.
654 SourceLocation TypeStartLoc
655 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
656 QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
657 TemplateArgs,
658 TypeStartLoc,
659 DeclarationName());
660 if (ExplicitTy.isNull())
661 return SemaRef.ExprError();
662
663 // Instantiate the subexpression.
664 OwningExprResult SubExpr = Visit(E->getSubExpr());
665 if (SubExpr.isInvalid())
666 return SemaRef.ExprError();
667
668 SourceLocation FakeLAngleLoc
669 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
670 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
671 SourceLocation FakeRParenLoc
672 = SemaRef.PP.getLocForEndOfToken(
673 E->getSubExpr()->getSourceRange().getEnd());
674 return SemaRef.ActOnCXXNamedCast(E->getOperatorLoc(), Kind,
675 /*FIXME:*/FakeLAngleLoc,
676 ExplicitTy.getAsOpaquePtr(),
677 /*FIXME:*/FakeRAngleLoc,
678 /*FIXME:*/FakeRAngleLoc,
679 move(SubExpr),
680 /*FIXME:*/FakeRParenLoc);
681}
682
683Sema::OwningExprResult
684TemplateExprInstantiator::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
685 return VisitCXXNamedCastExpr(E);
686}
687
688Sema::OwningExprResult
689TemplateExprInstantiator::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
690 return VisitCXXNamedCastExpr(E);
691}
692
693Sema::OwningExprResult
694TemplateExprInstantiator::VisitCXXReinterpretCastExpr(
695 CXXReinterpretCastExpr *E) {
696 return VisitCXXNamedCastExpr(E);
697}
698
699Sema::OwningExprResult
700TemplateExprInstantiator::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
701 return VisitCXXNamedCastExpr(E);
702}
703
Anders Carlsson0712d292009-05-15 20:26:03 +0000704Sema::OwningExprResult
705TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
706 QualType ThisType =
707 cast<CXXMethodDecl>(SemaRef.CurContext)->getThisType(SemaRef.Context);
708
709 CXXThisExpr *TE =
710 new (SemaRef.Context) CXXThisExpr(E->getLocStart(), ThisType);
711
712 return SemaRef.Owned(TE);
713}
714
Douglas Gregoraa6af222009-03-25 00:27:28 +0000715Sema::OwningExprResult
Douglas Gregor7e063902009-05-11 23:53:27 +0000716Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
Douglas Gregor50557a72009-05-15 20:47:12 +0000717 if (!E)
718 return Owned((Expr *)0);
719
Douglas Gregor7e063902009-05-11 23:53:27 +0000720 TemplateExprInstantiator Instantiator(*this, TemplateArgs);
Douglas Gregoraa6af222009-03-25 00:27:28 +0000721 return Instantiator.Visit(E);
722}