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