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