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