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