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