blob: 099ce278f1f452cd530c49d4bb0ae0183e03db41 [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 Gregorcde01732009-05-19 22:10:17 +000060 OwningExprResult VisitShuffleVectorExpr(ShuffleVectorExpr *E);
Douglas Gregorc9ecc572009-05-19 22:43:30 +000061 OwningExprResult VisitChooseExpr(ChooseExpr *E);
Douglas Gregordd027302009-05-19 23:10:31 +000062 OwningExprResult VisitVAArgExpr(VAArgExpr *E);
Douglas Gregor05295192009-05-19 23:29:16 +000063 // FIXME: InitListExpr
64 // FIXME: DesignatedInitExpr
65 // FIXME: ImplicitValueInitExpr
66 // FIXME: ExtVectorElementExpr
67 // FIXME: BlockExpr
68 // FIXME: BlockDeclRefExpr
Douglas Gregoraa6af222009-03-25 00:27:28 +000069 OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
70 OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
71 OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000072 OwningExprResult VisitCastExpr(CastExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000073 OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000074 OwningExprResult VisitExplicitCastExpr(ExplicitCastExpr *E);
75 OwningExprResult VisitCStyleCastExpr(CStyleCastExpr *E);
Douglas Gregor05295192009-05-19 23:29:16 +000076 // FIXME: CXXMemberCallExpr
Douglas Gregora3a7b8e2009-05-19 19:05:47 +000077 OwningExprResult VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
78 OwningExprResult VisitCXXStaticCastExpr(CXXStaticCastExpr *E);
79 OwningExprResult VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E);
80 OwningExprResult VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
81 OwningExprResult VisitCXXConstCastExpr(CXXConstCastExpr *E);
Anders Carlsson0712d292009-05-15 20:26:03 +000082 OwningExprResult VisitCXXThisExpr(CXXThisExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000083 OwningExprResult VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
84 OwningExprResult VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
Douglas Gregor05295192009-05-19 23:29:16 +000085 // FIXME: CXXTypeIdExpr
86 // FIXME: CXXThrowExpr
87 // FIXME: CXXDefaultArgExpr
Douglas Gregord94546a2009-05-20 21:38:11 +000088 OwningExprResult VisitCXXConstructExpr(CXXConstructExpr *E);
89 OwningExprResult VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
90 OwningExprResult VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
Douglas Gregor05295192009-05-19 23:29:16 +000091 // FIXME: CXXNewExpr
92 // FIXME: CXXDeleteExpr
93 // FIXME: UnaryTypeTraitExpr
94 // FIXME: QualifiedDeclRefExpr
Douglas Gregore06274d2009-05-20 21:51:01 +000095 OwningExprResult VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
Douglas Gregord81e6ca2009-05-20 18:46:25 +000096 OwningExprResult VisitCXXUnresolvedConstructExpr(
97 CXXUnresolvedConstructExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +000098 OwningExprResult VisitGNUNullExpr(GNUNullExpr *E);
Douglas Gregor4a2487a2009-05-19 00:38:01 +000099 OwningExprResult VisitUnresolvedFunctionNameExpr(
100 UnresolvedFunctionNameExpr *E);
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000101
Douglas Gregoraa6af222009-03-25 00:27:28 +0000102 // Base case. I'm supposed to ignore this.
103 Sema::OwningExprResult VisitStmt(Stmt *S) {
104 S->dump();
105 assert(false && "Cannot instantiate this kind of expression");
106 return SemaRef.ExprError();
107 }
108 };
109}
110
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000111Sema::OwningExprResult
112TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) {
113 return SemaRef.Clone(E);
114}
115
116Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000117TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
118 return SemaRef.Clone(E);
119}
120
121Sema::OwningExprResult
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000122TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) {
123 return SemaRef.Clone(E);
124}
125
126Sema::OwningExprResult
127TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) {
128 return SemaRef.Clone(E);
129}
130
131Sema::OwningExprResult
132TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) {
133 return SemaRef.Clone(E);
134}
135
Douglas Gregord8ac4362009-05-18 22:38:38 +0000136Sema::OwningExprResult
137TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
138 return SemaRef.Clone(E);
139}
140
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000141Sema::OwningExprResult
142TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
143 return SemaRef.Clone(E);
144}
145
146Sema::OwningExprResult
147TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
148 return SemaRef.Clone(E);
149}
150
151Sema::OwningExprResult
152TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) {
153 return SemaRef.Clone(E);
154}
155
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000156Sema::OwningExprResult
157TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
158 UnresolvedFunctionNameExpr *E) {
159 return SemaRef.Clone(E);
160}
161
Sebastian Redl8b0b4752009-05-16 18:50:46 +0000162Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000163TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
164 Decl *D = E->getDecl();
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000165 ValueDecl *NewD = 0;
Douglas Gregoraa6af222009-03-25 00:27:28 +0000166 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
167 assert(NTTP->getDepth() == 0 && "No nested templates yet");
168 const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
169 QualType T = Arg.getIntegralType();
170 if (T->isCharType() || T->isWideCharType())
171 return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
172 Arg.getAsIntegral()->getZExtValue(),
173 T->isWideCharType(),
174 T,
175 E->getSourceRange().getBegin()));
176 else if (T->isBooleanType())
177 return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
178 Arg.getAsIntegral()->getBoolValue(),
179 T,
180 E->getSourceRange().getBegin()));
181
182 return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
183 *Arg.getAsIntegral(),
184 T,
185 E->getSourceRange().getBegin()));
Douglas Gregordd027302009-05-19 23:10:31 +0000186 } else if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000187 NewD = SemaRef.CurrentInstantiationScope->getInstantiationOf(Parm);
Douglas Gregordd027302009-05-19 23:10:31 +0000188 } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
189 if (Var->hasLocalStorage())
190 NewD = SemaRef.CurrentInstantiationScope->getInstantiationOf(Var);
191 else
192 assert(false && "Cannot instantiation non-local variable declarations");
193 } else if (isa<FunctionDecl>(D) || isa<OverloadedFunctionDecl>(D)) {
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000194 // FIXME: Instantiate decl!
195 NewD = cast<ValueDecl>(D);
Douglas Gregordd027302009-05-19 23:10:31 +0000196 } else
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000197 assert(false && "Unhandled declaratrion reference kind");
198
199 if (!NewD)
200 return SemaRef.ExprError();
201
202 QualType T = NewD->getType();
203 return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
Douglas Gregor48dd19b2009-05-14 21:44:34 +0000204 T.getNonReferenceType(),
205 E->getLocation(),
206 T->isDependentType(),
207 T->isDependentType()));
Douglas Gregoraa6af222009-03-25 00:27:28 +0000208}
209
210Sema::OwningExprResult
211TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
212 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
213 if (SubExpr.isInvalid())
214 return SemaRef.ExprError();
215
216 return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
217 E->getLParen(), E->getRParen(),
218 (Expr *)SubExpr.release()));
219}
220
221Sema::OwningExprResult
222TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
223 Sema::OwningExprResult Arg = Visit(E->getSubExpr());
224 if (Arg.isInvalid())
225 return SemaRef.ExprError();
226
227 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
228 E->getOpcode(),
229 move(Arg));
230}
231
232Sema::OwningExprResult
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000233TemplateExprInstantiator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
234 Sema::OwningExprResult LHS = Visit(E->getLHS());
235 if (LHS.isInvalid())
236 return SemaRef.ExprError();
237
238 Sema::OwningExprResult RHS = Visit(E->getRHS());
239 if (RHS.isInvalid())
240 return SemaRef.ExprError();
241
242 // Since the overloaded array-subscript operator (operator[]) can
243 // only be a member function, we can make several simplifying
244 // assumptions here:
245 // 1) Normal name lookup (from the current scope) will not ever
246 // find any declarations of operator[] that won't also be found be
247 // member operator lookup, so it is safe to pass a NULL Scope
248 // during the instantiation to avoid the lookup entirely.
249 //
250 // 2) Neither normal name lookup nor argument-dependent lookup at
251 // template definition time will find any operators that won't be
252 // found at template instantiation time, so we do not need to
253 // cache the results of name lookup as we do for the binary
254 // operators.
255 SourceLocation LLocFake = ((Expr*)LHS.get())->getSourceRange().getBegin();
256 return SemaRef.ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
257 /*FIXME:*/LLocFake,
258 move(RHS),
259 E->getRBracketLoc());
260}
261
Douglas Gregor4a2487a2009-05-19 00:38:01 +0000262Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) {
263 // Instantiate callee
264 OwningExprResult Callee = Visit(E->getCallee());
265 if (Callee.isInvalid())
266 return SemaRef.ExprError();
267
268 // Instantiate arguments
269 llvm::SmallVector<Expr*, 8> Args;
270 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
271 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
272 OwningExprResult Arg = Visit(E->getArg(I));
273 if (Arg.isInvalid()) {
274 for (unsigned Victim = 0; Victim != I; ++Victim)
275 Args[Victim]->Destroy(SemaRef.Context);
276 return SemaRef.ExprError();
277 }
278
279 FakeCommaLocs.push_back(
280 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
281 Args.push_back(Arg.takeAs<Expr>());
282 }
283
284 SourceLocation FakeLParenLoc
285 = ((Expr *)Callee.get())->getSourceRange().getBegin();
286 return SemaRef.ActOnCallExpr(/*Scope=*/0, move(Callee),
287 /*FIXME:*/FakeLParenLoc,
288 Sema::MultiExprArg(SemaRef,
289 (void **)&Args.front(),
290 Args.size()),
291 /*FIXME:*/&FakeCommaLocs.front(),
292 E->getRParenLoc());
293}
294
Douglas Gregor3384c9c2009-05-19 00:01:19 +0000295Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000296TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
297 Sema::OwningExprResult LHS = Visit(E->getLHS());
298 if (LHS.isInvalid())
299 return SemaRef.ExprError();
300
301 Sema::OwningExprResult RHS = Visit(E->getRHS());
302 if (RHS.isInvalid())
303 return SemaRef.ExprError();
304
305 Sema::OwningExprResult Result
306 = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
307 E->getOpcode(),
308 (Expr *)LHS.get(),
309 (Expr *)RHS.get());
310 if (Result.isInvalid())
311 return SemaRef.ExprError();
312
313 LHS.release();
314 RHS.release();
315 return move(Result);
316}
317
318Sema::OwningExprResult
Douglas Gregor6731c312009-05-19 20:02:01 +0000319TemplateExprInstantiator::VisitCompoundAssignOperator(
320 CompoundAssignOperator *E) {
321 return VisitBinaryOperator(E);
322}
323
324Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000325TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
326 Sema::OwningExprResult First = Visit(E->getArg(0));
327 if (First.isInvalid())
328 return SemaRef.ExprError();
329
330 Expr *Args[2] = { (Expr *)First.get(), 0 };
331
332 Sema::OwningExprResult Second(SemaRef);
333 if (E->getNumArgs() == 2) {
334 Second = Visit(E->getArg(1));
335
336 if (Second.isInvalid())
337 return SemaRef.ExprError();
338
339 Args[1] = (Expr *)Second.get();
340 }
341
342 if (!E->isTypeDependent()) {
343 // Since our original expression was not type-dependent, we do not
344 // perform lookup again at instantiation time (C++ [temp.dep]p1).
345 // Instead, we just build the new overloaded operator call
346 // expression.
Douglas Gregor05295192009-05-19 23:29:16 +0000347 OwningExprResult Callee = Visit(E->getCallee());
348 if (Callee.isInvalid())
349 return SemaRef.ExprError();
350
Douglas Gregoraa6af222009-03-25 00:27:28 +0000351 First.release();
352 Second.release();
Douglas Gregor05295192009-05-19 23:29:16 +0000353
Douglas Gregoraa6af222009-03-25 00:27:28 +0000354 return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
355 SemaRef.Context,
356 E->getOperator(),
Douglas Gregor05295192009-05-19 23:29:16 +0000357 Callee.takeAs<Expr>(),
Douglas Gregoraa6af222009-03-25 00:27:28 +0000358 Args, E->getNumArgs(),
359 E->getType(),
360 E->getOperatorLoc()));
361 }
362
363 bool isPostIncDec = E->getNumArgs() == 2 &&
364 (E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
365 if (E->getNumArgs() == 1 || isPostIncDec) {
366 if (!Args[0]->getType()->isOverloadableType()) {
367 // The argument is not of overloadable type, so try to create a
368 // built-in unary operation.
369 UnaryOperator::Opcode Opc
370 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
371
372 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
373 move(First));
374 }
375
376 // Fall through to perform overload resolution
377 } else {
378 assert(E->getNumArgs() == 2 && "Expected binary operation");
379
380 Sema::OwningExprResult Result(SemaRef);
381 if (!Args[0]->getType()->isOverloadableType() &&
382 !Args[1]->getType()->isOverloadableType()) {
383 // Neither of the arguments is an overloadable type, so try to
384 // create a built-in binary operation.
385 BinaryOperator::Opcode Opc =
386 BinaryOperator::getOverloadedOpcode(E->getOperator());
387 Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
388 Args[0], Args[1]);
389 if (Result.isInvalid())
390 return SemaRef.ExprError();
391
392 First.release();
393 Second.release();
394 return move(Result);
395 }
396
397 // Fall through to perform overload resolution.
398 }
399
400 // Compute the set of functions that were found at template
401 // definition time.
402 Sema::FunctionSet Functions;
403 DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
404 OverloadedFunctionDecl *Overloads
405 = cast<OverloadedFunctionDecl>(DRE->getDecl());
406
407 // FIXME: Do we have to check
408 // IsAcceptableNonMemberOperatorCandidate for each of these?
409 for (OverloadedFunctionDecl::function_iterator
410 F = Overloads->function_begin(),
411 FEnd = Overloads->function_end();
412 F != FEnd; ++F)
413 Functions.insert(*F);
414
415 // Add any functions found via argument-dependent lookup.
416 DeclarationName OpName
417 = SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
418 SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
419
420 // Create the overloaded operator invocation.
421 if (E->getNumArgs() == 1 || isPostIncDec) {
422 UnaryOperator::Opcode Opc
423 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
424 return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
425 Functions, move(First));
426 }
427
Mike Stump390b4cc2009-05-16 07:39:55 +0000428 // FIXME: This would be far less ugly if CreateOverloadedBinOp took in ExprArg
429 // arguments!
Douglas Gregoraa6af222009-03-25 00:27:28 +0000430 BinaryOperator::Opcode Opc =
431 BinaryOperator::getOverloadedOpcode(E->getOperator());
432 OwningExprResult Result
433 = SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
434 Functions, Args[0], Args[1]);
435
436 if (Result.isInvalid())
437 return SemaRef.ExprError();
438
439 First.release();
440 Second.release();
441 return move(Result);
442}
443
Douglas Gregor4a2e2042009-05-15 21:45:53 +0000444Sema::OwningExprResult
445TemplateExprInstantiator::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
446 VarDecl *Var
447 = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
448 SemaRef.CurContext,
449 TemplateArgs));
450 if (!Var)
451 return SemaRef.ExprError();
452
Douglas Gregore06274d2009-05-20 21:51:01 +0000453 SemaRef.CurrentInstantiationScope->InstantiatedLocal(E->getVarDecl(), Var);
Douglas Gregor4a2e2042009-05-15 21:45:53 +0000454 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(
455 E->getStartLoc(),
456 SourceLocation(),
457 Var));
458}
459
Douglas Gregoraa6af222009-03-25 00:27:28 +0000460Sema::OwningExprResult
461TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
462 Sema::OwningExprResult Cond = Visit(E->getCond());
463 if (Cond.isInvalid())
464 return SemaRef.ExprError();
465
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000466 Sema::OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(),
467 TemplateArgs);
468 if (LHS.isInvalid())
Douglas Gregoraa6af222009-03-25 00:27:28 +0000469 return SemaRef.ExprError();
470
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000471 Sema::OwningExprResult RHS = Visit(E->getRHS());
472 if (RHS.isInvalid())
Douglas Gregoraa6af222009-03-25 00:27:28 +0000473 return SemaRef.ExprError();
474
475 if (!E->isTypeDependent()) {
476 // Since our original expression was not type-dependent, we do not
477 // perform lookup again at instantiation time (C++ [temp.dep]p1).
478 // Instead, we just build the new conditional operator call expression.
479 return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
480 Cond.takeAs<Expr>(),
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000481 LHS.takeAs<Expr>(),
482 RHS.takeAs<Expr>(),
Douglas Gregoraa6af222009-03-25 00:27:28 +0000483 E->getType()));
484 }
485
486
487 return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
488 /*FIXME*/E->getFalseExpr()->getLocStart(),
Douglas Gregord5f3a0f2009-05-19 20:13:50 +0000489 move(Cond), move(LHS), move(RHS));
Douglas Gregoraa6af222009-03-25 00:27:28 +0000490}
491
Douglas Gregorcd938172009-05-19 20:31:21 +0000492Sema::OwningExprResult TemplateExprInstantiator::VisitStmtExpr(StmtExpr *E) {
493 Sema::OwningStmtResult SubStmt = SemaRef.InstantiateStmt(E->getSubStmt(),
494 TemplateArgs);
495 if (SubStmt.isInvalid())
496 return SemaRef.ExprError();
497
498 return SemaRef.ActOnStmtExpr(E->getLParenLoc(), move(SubStmt),
499 E->getRParenLoc());
500}
501
Douglas Gregoraa6af222009-03-25 00:27:28 +0000502Sema::OwningExprResult
Douglas Gregordc241b42009-05-19 20:55:31 +0000503TemplateExprInstantiator::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregorc12a9c52009-05-19 22:28:02 +0000504 assert(false && "__builtin_types_compatible_p is not legal in C++");
505 return SemaRef.ExprError();
Douglas Gregordc241b42009-05-19 20:55:31 +0000506}
507
508Sema::OwningExprResult
Douglas Gregorcde01732009-05-19 22:10:17 +0000509TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
510 // FIXME: Better solution for this!
511 llvm::SmallVector<Expr *, 8> SubExprs;
512 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
513 OwningExprResult SubExpr = Visit(E->getExpr(I));
514 if (SubExpr.isInvalid()) {
515 for (unsigned Victim = 0; Victim != I; ++Victim)
516 SubExprs[I]->Destroy(SemaRef.Context);
517 return SemaRef.ExprError();
518 }
519
520 SubExprs.push_back(SubExpr.takeAs<Expr>());
521 }
522
523 // Find the declaration for __builtin_shufflevector
524 const IdentifierInfo &Name
525 = SemaRef.Context.Idents.get("__builtin_shufflevector");
526 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
527 DeclContext::lookup_result Lookup
528 = TUDecl->lookup(SemaRef.Context, DeclarationName(&Name));
529 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
530
531 // Build a reference to the __builtin_shufflevector builtin
532 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
533 Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
534 E->getBuiltinLoc(),
535 false, false);
536 SemaRef.UsualUnaryConversions(Callee);
537
538 // Build the CallExpr
539 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
540 &SubExprs[0],
541 SubExprs.size(),
542 Builtin->getResultType(),
543 E->getRParenLoc());
544 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
545
546 // Type-check the __builtin_shufflevector expression.
547 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
548 if (Result.isInvalid())
549 return SemaRef.ExprError();
550
551 OwnedCall.release();
552 return move(Result);
553}
554
555Sema::OwningExprResult
Douglas Gregorc9ecc572009-05-19 22:43:30 +0000556TemplateExprInstantiator::VisitChooseExpr(ChooseExpr *E) {
557 OwningExprResult Cond = Visit(E->getCond());
558 if (Cond.isInvalid())
559 return SemaRef.ExprError();
560
561 OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(), TemplateArgs);
562 if (LHS.isInvalid())
563 return SemaRef.ExprError();
564
565 OwningExprResult RHS = Visit(E->getRHS());
566 if (RHS.isInvalid())
567 return SemaRef.ExprError();
568
569 return SemaRef.ActOnChooseExpr(E->getBuiltinLoc(),
570 move(Cond), move(LHS), move(RHS),
571 E->getRParenLoc());
572}
573
Douglas Gregordd027302009-05-19 23:10:31 +0000574Sema::OwningExprResult TemplateExprInstantiator::VisitVAArgExpr(VAArgExpr *E) {
575 OwningExprResult SubExpr = Visit(E->getSubExpr());
576 if (SubExpr.isInvalid())
577 return SemaRef.ExprError();
578
579 SourceLocation FakeTypeLoc
580 = SemaRef.PP.getLocForEndOfToken(E->getSubExpr()->getSourceRange()
581 .getEnd());
582 QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
583 /*FIXME:*/FakeTypeLoc,
584 DeclarationName());
585 if (T.isNull())
586 return SemaRef.ExprError();
587
588 return SemaRef.ActOnVAArg(E->getBuiltinLoc(), move(SubExpr),
589 T.getAsOpaquePtr(), E->getRParenLoc());
590}
591
Douglas Gregorc9ecc572009-05-19 22:43:30 +0000592Sema::OwningExprResult
Douglas Gregoraa6af222009-03-25 00:27:28 +0000593TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
594 bool isSizeOf = E->isSizeOf();
595
596 if (E->isArgumentType()) {
597 QualType T = E->getArgumentType();
598 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000599 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000600 /*FIXME*/E->getOperatorLoc(),
601 &SemaRef.PP.getIdentifierTable().get("sizeof"));
602 if (T.isNull())
603 return SemaRef.ExprError();
604 }
605
606 return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
607 E->getSourceRange());
608 }
609
610 Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
611 if (Arg.isInvalid())
612 return SemaRef.ExprError();
613
614 Sema::OwningExprResult Result
615 = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
616 isSizeOf, E->getSourceRange());
617 if (Result.isInvalid())
618 return SemaRef.ExprError();
619
620 Arg.release();
621 return move(Result);
622}
623
624Sema::OwningExprResult
625TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
Douglas Gregorab452ba2009-03-26 23:50:42 +0000626 NestedNameSpecifier *NNS
627 = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
628 E->getQualifierRange(),
Douglas Gregor7e063902009-05-11 23:53:27 +0000629 TemplateArgs);
Douglas Gregorab452ba2009-03-26 23:50:42 +0000630 if (!NNS)
Douglas Gregoraa6af222009-03-25 00:27:28 +0000631 return SemaRef.ExprError();
632
Douglas Gregorab452ba2009-03-26 23:50:42 +0000633 CXXScopeSpec SS;
634 SS.setRange(E->getQualifierRange());
635 SS.setScopeRep(NNS);
636
Douglas Gregoraa6af222009-03-25 00:27:28 +0000637 // FIXME: We're passing in a NULL scope, because
638 // ActOnDeclarationNameExpr doesn't actually use the scope when we
639 // give it a non-empty scope specifier. Investigate whether it would
640 // be better to refactor ActOnDeclarationNameExpr.
641 return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
642 E->getDeclName(),
643 /*HasTrailingLParen=*/false,
644 &SS,
645 /*FIXME:isAddressOfOperand=*/false);
646}
647
648Sema::OwningExprResult
649TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
650 CXXTemporaryObjectExpr *E) {
651 QualType T = E->getType();
652 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000653 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000654 E->getTypeBeginLoc(), DeclarationName());
655 if (T.isNull())
656 return SemaRef.ExprError();
657 }
658
659 llvm::SmallVector<Expr *, 16> Args;
660 Args.reserve(E->getNumArgs());
661 bool Invalid = false;
662 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
663 ArgEnd = E->arg_end();
664 Arg != ArgEnd; ++Arg) {
665 OwningExprResult InstantiatedArg = Visit(*Arg);
666 if (InstantiatedArg.isInvalid()) {
667 Invalid = true;
668 break;
669 }
670
671 Args.push_back((Expr *)InstantiatedArg.release());
672 }
673
674 if (!Invalid) {
675 SourceLocation CommaLoc;
676 // FIXME: HACK!
677 if (Args.size() > 1)
678 CommaLoc
679 = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd());
680 Sema::OwningExprResult Result(
681 SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
682 /*, FIXME*/),
683 T.getAsOpaquePtr(),
684 /*FIXME*/E->getTypeBeginLoc(),
685 Sema::MultiExprArg(SemaRef,
686 (void**)&Args[0],
687 Args.size()),
688 /*HACK*/&CommaLoc,
689 E->getSourceRange().getEnd()));
690 // At this point, Args no longer owns the arguments, no matter what.
691 return move(Result);
692 }
693
694 // Clean up the instantiated arguments.
695 // FIXME: Would rather do this with RAII.
696 for (unsigned Idx = 0; Idx < Args.size(); ++Idx)
697 SemaRef.DeleteExpr(Args[Idx]);
698
699 return SemaRef.ExprError();
700}
701
Douglas Gregora3a7b8e2009-05-19 19:05:47 +0000702Sema::OwningExprResult TemplateExprInstantiator::VisitCastExpr(CastExpr *E) {
703 assert(false && "Cannot instantiate abstract CastExpr");
704 return SemaRef.ExprError();
705}
706
Douglas Gregoraa6af222009-03-25 00:27:28 +0000707Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
708 ImplicitCastExpr *E) {
709 assert(!E->isTypeDependent() && "Implicit casts must have known types");
710
711 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
712 if (SubExpr.isInvalid())
713 return SemaRef.ExprError();
714
715 ImplicitCastExpr *ICE =
716 new (SemaRef.Context) ImplicitCastExpr(E->getType(),
717 (Expr *)SubExpr.release(),
718 E->isLvalueCast());
719 return SemaRef.Owned(ICE);
720}
721
Douglas Gregora3a7b8e2009-05-19 19:05:47 +0000722Sema::OwningExprResult
723TemplateExprInstantiator::VisitExplicitCastExpr(ExplicitCastExpr *E) {
724 assert(false && "Cannot instantiate abstract ExplicitCastExpr");
725 return SemaRef.ExprError();
726}
727
728Sema::OwningExprResult
729TemplateExprInstantiator::VisitCStyleCastExpr(CStyleCastExpr *E) {
730 // Instantiate the type that we're casting to.
731 SourceLocation TypeStartLoc
732 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
733 QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
734 TemplateArgs,
735 TypeStartLoc,
736 DeclarationName());
737 if (ExplicitTy.isNull())
738 return SemaRef.ExprError();
739
740 // Instantiate the subexpression.
741 OwningExprResult SubExpr = Visit(E->getSubExpr());
742 if (SubExpr.isInvalid())
743 return SemaRef.ExprError();
744
745 return SemaRef.ActOnCastExpr(E->getLParenLoc(),
746 ExplicitTy.getAsOpaquePtr(),
747 E->getRParenLoc(),
748 move(SubExpr));
749}
750
751Sema::OwningExprResult
752TemplateExprInstantiator::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
753 // Figure out which cast operator we're dealing with.
754 tok::TokenKind Kind;
755 switch (E->getStmtClass()) {
756 case Stmt::CXXStaticCastExprClass:
757 Kind = tok::kw_static_cast;
758 break;
759
760 case Stmt::CXXDynamicCastExprClass:
761 Kind = tok::kw_dynamic_cast;
762 break;
763
764 case Stmt::CXXReinterpretCastExprClass:
765 Kind = tok::kw_reinterpret_cast;
766 break;
767
768 case Stmt::CXXConstCastExprClass:
769 Kind = tok::kw_const_cast;
770 break;
771
772 default:
773 assert(false && "Invalid C++ named cast");
774 return SemaRef.ExprError();
775 }
776
777 // Instantiate the type that we're casting to.
778 SourceLocation TypeStartLoc
779 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
780 QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
781 TemplateArgs,
782 TypeStartLoc,
783 DeclarationName());
784 if (ExplicitTy.isNull())
785 return SemaRef.ExprError();
786
787 // Instantiate the subexpression.
788 OwningExprResult SubExpr = Visit(E->getSubExpr());
789 if (SubExpr.isInvalid())
790 return SemaRef.ExprError();
791
792 SourceLocation FakeLAngleLoc
793 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
794 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
795 SourceLocation FakeRParenLoc
796 = SemaRef.PP.getLocForEndOfToken(
797 E->getSubExpr()->getSourceRange().getEnd());
798 return SemaRef.ActOnCXXNamedCast(E->getOperatorLoc(), Kind,
799 /*FIXME:*/FakeLAngleLoc,
800 ExplicitTy.getAsOpaquePtr(),
801 /*FIXME:*/FakeRAngleLoc,
802 /*FIXME:*/FakeRAngleLoc,
803 move(SubExpr),
804 /*FIXME:*/FakeRParenLoc);
805}
806
807Sema::OwningExprResult
808TemplateExprInstantiator::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
809 return VisitCXXNamedCastExpr(E);
810}
811
812Sema::OwningExprResult
813TemplateExprInstantiator::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
814 return VisitCXXNamedCastExpr(E);
815}
816
817Sema::OwningExprResult
818TemplateExprInstantiator::VisitCXXReinterpretCastExpr(
819 CXXReinterpretCastExpr *E) {
820 return VisitCXXNamedCastExpr(E);
821}
822
823Sema::OwningExprResult
824TemplateExprInstantiator::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
825 return VisitCXXNamedCastExpr(E);
826}
827
Anders Carlsson0712d292009-05-15 20:26:03 +0000828Sema::OwningExprResult
829TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
830 QualType ThisType =
831 cast<CXXMethodDecl>(SemaRef.CurContext)->getThisType(SemaRef.Context);
832
833 CXXThisExpr *TE =
834 new (SemaRef.Context) CXXThisExpr(E->getLocStart(), ThisType);
835
836 return SemaRef.Owned(TE);
837}
838
Douglas Gregoraa6af222009-03-25 00:27:28 +0000839Sema::OwningExprResult
Douglas Gregord94546a2009-05-20 21:38:11 +0000840TemplateExprInstantiator::VisitCXXConstructExpr(CXXConstructExpr *E) {
841 assert(!cast<CXXRecordDecl>(E->getConstructor()->getDeclContext())
842 ->isDependentType() && "Dependent constructor shouldn't be here");
843
844 QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
845 /*FIXME*/E->getSourceRange().getBegin(),
846 DeclarationName());
847 if (T.isNull())
848 return SemaRef.ExprError();
849
850 bool Invalid = false;
851 llvm::SmallVector<Expr *, 8> Args;
852 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
853 ArgEnd = E->arg_end();
854 Arg != ArgEnd; ++Arg) {
855 OwningExprResult ArgInst = Visit(*Arg);
856 if (ArgInst.isInvalid()) {
857 Invalid = true;
858 break;
859 }
860
861 Args.push_back(ArgInst.takeAs<Expr>());
862 }
863
864
865 VarDecl *Var = 0;
866 if (!Invalid) {
867 Var = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
868 SemaRef.CurContext,
869 TemplateArgs));
870 if (!Var)
871 Invalid = true;
872 }
873
874 if (Invalid) {
875 for (unsigned I = 0, N = Args.size(); I != N; ++I)
876 Args[I]->Destroy(SemaRef.Context);
877
878 return SemaRef.ExprError();
879 }
880
Douglas Gregore06274d2009-05-20 21:51:01 +0000881 SemaRef.CurrentInstantiationScope->InstantiatedLocal(E->getVarDecl(), Var);
Douglas Gregord94546a2009-05-20 21:38:11 +0000882 return SemaRef.Owned(CXXConstructExpr::Create(SemaRef.Context, Var, T,
883 E->getConstructor(),
884 E->isElidable(),
885 &Args.front(), Args.size()));
886}
887
888Sema::OwningExprResult
889TemplateExprInstantiator::VisitCXXFunctionalCastExpr(
890 CXXFunctionalCastExpr *E) {
891 // Instantiate the type that we're casting to.
892 QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
893 TemplateArgs,
894 E->getTypeBeginLoc(),
895 DeclarationName());
896 if (ExplicitTy.isNull())
897 return SemaRef.ExprError();
898
899 // Instantiate the subexpression.
900 OwningExprResult SubExpr = Visit(E->getSubExpr());
901 if (SubExpr.isInvalid())
902 return SemaRef.ExprError();
903
904 // FIXME: The end of the type's source range is wrong
905 Expr *Sub = SubExpr.takeAs<Expr>();
906 return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()),
907 ExplicitTy.getAsOpaquePtr(),
908 /*FIXME:*/E->getTypeBeginLoc(),
909 Sema::MultiExprArg(SemaRef,
910 (void **)&Sub,
911 1),
912 0,
913 E->getRParenLoc());
914}
915
916Sema::OwningExprResult
917TemplateExprInstantiator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
918 return SemaRef.Clone(E);
919}
920
921Sema::OwningExprResult
Douglas Gregore06274d2009-05-20 21:51:01 +0000922TemplateExprInstantiator::VisitCXXExprWithTemporaries(
923 CXXExprWithTemporaries *E) {
924 OwningExprResult SubExpr = Visit(E->getSubExpr());
925 if (SubExpr.isInvalid())
926 return SemaRef.ExprError();
927
928 return SemaRef.ActOnFinishFullExpr(move(SubExpr));
929}
930
931Sema::OwningExprResult
Douglas Gregord81e6ca2009-05-20 18:46:25 +0000932TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr(
933 CXXUnresolvedConstructExpr *E) {
934 QualType T = SemaRef.InstantiateType(E->getTypeAsWritten(), TemplateArgs,
935 E->getTypeBeginLoc(),
936 DeclarationName());
937 if (T.isNull())
938 return SemaRef.ExprError();
939
940 llvm::SmallVector<Expr *, 8> Args;
941 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
942 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
943 ArgEnd = E->arg_end();
944 Arg != ArgEnd; ++Arg) {
945 OwningExprResult InstArg = Visit(*Arg);
946 if (InstArg.isInvalid()) {
947 for (unsigned I = 0; I != Args.size(); ++I)
948 Args[I]->Destroy(SemaRef.Context);
949 return SemaRef.ExprError();
950 }
951
952 FakeCommaLocs.push_back(
953 SemaRef.PP.getLocForEndOfToken((*Arg)->getSourceRange().getEnd()));
954 Args.push_back(InstArg.takeAs<Expr>());
955 }
956
957 // FIXME: The end of the type range isn't exactly correct.
958 // FIXME: we're faking the locations of the commas
959 return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc(),
960 E->getLParenLoc()),
961 T.getAsOpaquePtr(),
962 E->getLParenLoc(),
963 Sema::MultiExprArg(SemaRef,
964 (void **)&Args.front(),
965 Args.size()),
966 &FakeCommaLocs.front(),
967 E->getRParenLoc());
968}
969
970Sema::OwningExprResult
Douglas Gregor7e063902009-05-11 23:53:27 +0000971Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
Douglas Gregor50557a72009-05-15 20:47:12 +0000972 if (!E)
973 return Owned((Expr *)0);
974
Douglas Gregor7e063902009-05-11 23:53:27 +0000975 TemplateExprInstantiator Instantiator(*this, TemplateArgs);
Douglas Gregoraa6af222009-03-25 00:27:28 +0000976 return Instantiator.Visit(E);
977}