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