blob: 08c388efea1736912178fbca38d29b6fb0401724 [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
36 // FIXME: Once we get closer to completion, replace these
37 // manually-written declarations with automatically-generated ones
38 // from clang/AST/StmtNodes.def.
39 OwningExprResult VisitIntegerLiteral(IntegerLiteral *E);
40 OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
41 OwningExprResult VisitParenExpr(ParenExpr *E);
42 OwningExprResult VisitUnaryOperator(UnaryOperator *E);
43 OwningExprResult VisitBinaryOperator(BinaryOperator *E);
44 OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
45 OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
46 OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
47 OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
48 OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
49 OwningExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
Anders Carlsson0712d292009-05-15 20:26:03 +000050 OwningExprResult VisitCXXThisExpr(CXXThisExpr *E);
Douglas Gregoraa6af222009-03-25 00:27:28 +000051
52 // Base case. I'm supposed to ignore this.
53 Sema::OwningExprResult VisitStmt(Stmt *S) {
54 S->dump();
55 assert(false && "Cannot instantiate this kind of expression");
56 return SemaRef.ExprError();
57 }
58 };
59}
60
61Sema::OwningExprResult
62TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
63 return SemaRef.Clone(E);
64}
65
66Sema::OwningExprResult
67TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
68 Decl *D = E->getDecl();
69 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
70 assert(NTTP->getDepth() == 0 && "No nested templates yet");
71 const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
72 QualType T = Arg.getIntegralType();
73 if (T->isCharType() || T->isWideCharType())
74 return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
75 Arg.getAsIntegral()->getZExtValue(),
76 T->isWideCharType(),
77 T,
78 E->getSourceRange().getBegin()));
79 else if (T->isBooleanType())
80 return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
81 Arg.getAsIntegral()->getBoolValue(),
82 T,
83 E->getSourceRange().getBegin()));
84
85 return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
86 *Arg.getAsIntegral(),
87 T,
88 E->getSourceRange().getBegin()));
Douglas Gregor48dd19b2009-05-14 21:44:34 +000089 } else if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
90 ParmVarDecl *ParmInst
91 = SemaRef.CurrentInstantiationScope->getInstantiationOf(Parm);
92 QualType T = ParmInst->getType();
93 return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(ParmInst,
94 T.getNonReferenceType(),
95 E->getLocation(),
96 T->isDependentType(),
97 T->isDependentType()));
Douglas Gregoraa6af222009-03-25 00:27:28 +000098 } else
99 assert(false && "Can't handle arbitrary declaration references");
100
101 return SemaRef.ExprError();
102}
103
104Sema::OwningExprResult
105TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
106 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
107 if (SubExpr.isInvalid())
108 return SemaRef.ExprError();
109
110 return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
111 E->getLParen(), E->getRParen(),
112 (Expr *)SubExpr.release()));
113}
114
115Sema::OwningExprResult
116TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
117 Sema::OwningExprResult Arg = Visit(E->getSubExpr());
118 if (Arg.isInvalid())
119 return SemaRef.ExprError();
120
121 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
122 E->getOpcode(),
123 move(Arg));
124}
125
126Sema::OwningExprResult
127TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
128 Sema::OwningExprResult LHS = Visit(E->getLHS());
129 if (LHS.isInvalid())
130 return SemaRef.ExprError();
131
132 Sema::OwningExprResult RHS = Visit(E->getRHS());
133 if (RHS.isInvalid())
134 return SemaRef.ExprError();
135
136 Sema::OwningExprResult Result
137 = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
138 E->getOpcode(),
139 (Expr *)LHS.get(),
140 (Expr *)RHS.get());
141 if (Result.isInvalid())
142 return SemaRef.ExprError();
143
144 LHS.release();
145 RHS.release();
146 return move(Result);
147}
148
149Sema::OwningExprResult
150TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
151 Sema::OwningExprResult First = Visit(E->getArg(0));
152 if (First.isInvalid())
153 return SemaRef.ExprError();
154
155 Expr *Args[2] = { (Expr *)First.get(), 0 };
156
157 Sema::OwningExprResult Second(SemaRef);
158 if (E->getNumArgs() == 2) {
159 Second = Visit(E->getArg(1));
160
161 if (Second.isInvalid())
162 return SemaRef.ExprError();
163
164 Args[1] = (Expr *)Second.get();
165 }
166
167 if (!E->isTypeDependent()) {
168 // Since our original expression was not type-dependent, we do not
169 // perform lookup again at instantiation time (C++ [temp.dep]p1).
170 // Instead, we just build the new overloaded operator call
171 // expression.
172 First.release();
173 Second.release();
174 // FIXME: Don't reuse the callee here. We need to instantiate it.
175 return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
176 SemaRef.Context,
177 E->getOperator(),
178 E->getCallee(),
179 Args, E->getNumArgs(),
180 E->getType(),
181 E->getOperatorLoc()));
182 }
183
184 bool isPostIncDec = E->getNumArgs() == 2 &&
185 (E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
186 if (E->getNumArgs() == 1 || isPostIncDec) {
187 if (!Args[0]->getType()->isOverloadableType()) {
188 // The argument is not of overloadable type, so try to create a
189 // built-in unary operation.
190 UnaryOperator::Opcode Opc
191 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
192
193 return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
194 move(First));
195 }
196
197 // Fall through to perform overload resolution
198 } else {
199 assert(E->getNumArgs() == 2 && "Expected binary operation");
200
201 Sema::OwningExprResult Result(SemaRef);
202 if (!Args[0]->getType()->isOverloadableType() &&
203 !Args[1]->getType()->isOverloadableType()) {
204 // Neither of the arguments is an overloadable type, so try to
205 // create a built-in binary operation.
206 BinaryOperator::Opcode Opc =
207 BinaryOperator::getOverloadedOpcode(E->getOperator());
208 Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
209 Args[0], Args[1]);
210 if (Result.isInvalid())
211 return SemaRef.ExprError();
212
213 First.release();
214 Second.release();
215 return move(Result);
216 }
217
218 // Fall through to perform overload resolution.
219 }
220
221 // Compute the set of functions that were found at template
222 // definition time.
223 Sema::FunctionSet Functions;
224 DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
225 OverloadedFunctionDecl *Overloads
226 = cast<OverloadedFunctionDecl>(DRE->getDecl());
227
228 // FIXME: Do we have to check
229 // IsAcceptableNonMemberOperatorCandidate for each of these?
230 for (OverloadedFunctionDecl::function_iterator
231 F = Overloads->function_begin(),
232 FEnd = Overloads->function_end();
233 F != FEnd; ++F)
234 Functions.insert(*F);
235
236 // Add any functions found via argument-dependent lookup.
237 DeclarationName OpName
238 = SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
239 SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
240
241 // Create the overloaded operator invocation.
242 if (E->getNumArgs() == 1 || isPostIncDec) {
243 UnaryOperator::Opcode Opc
244 = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
245 return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
246 Functions, move(First));
247 }
248
249 // FIXME: This would be far less ugly if CreateOverloadedBinOp took
250 // in ExprArg arguments!
251 BinaryOperator::Opcode Opc =
252 BinaryOperator::getOverloadedOpcode(E->getOperator());
253 OwningExprResult Result
254 = SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
255 Functions, Args[0], Args[1]);
256
257 if (Result.isInvalid())
258 return SemaRef.ExprError();
259
260 First.release();
261 Second.release();
262 return move(Result);
263}
264
265Sema::OwningExprResult
266TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
267 Sema::OwningExprResult Cond = Visit(E->getCond());
268 if (Cond.isInvalid())
269 return SemaRef.ExprError();
270
271 // FIXME: use getLHS() and cope with NULLness
272 Sema::OwningExprResult True = Visit(E->getTrueExpr());
273 if (True.isInvalid())
274 return SemaRef.ExprError();
275
276 Sema::OwningExprResult False = Visit(E->getFalseExpr());
277 if (False.isInvalid())
278 return SemaRef.ExprError();
279
280 if (!E->isTypeDependent()) {
281 // Since our original expression was not type-dependent, we do not
282 // perform lookup again at instantiation time (C++ [temp.dep]p1).
283 // Instead, we just build the new conditional operator call expression.
284 return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
285 Cond.takeAs<Expr>(),
286 True.takeAs<Expr>(),
287 False.takeAs<Expr>(),
288 E->getType()));
289 }
290
291
292 return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
293 /*FIXME*/E->getFalseExpr()->getLocStart(),
294 move(Cond), move(True), move(False));
295}
296
297Sema::OwningExprResult
298TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
299 bool isSizeOf = E->isSizeOf();
300
301 if (E->isArgumentType()) {
302 QualType T = E->getArgumentType();
303 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000304 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000305 /*FIXME*/E->getOperatorLoc(),
306 &SemaRef.PP.getIdentifierTable().get("sizeof"));
307 if (T.isNull())
308 return SemaRef.ExprError();
309 }
310
311 return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
312 E->getSourceRange());
313 }
314
315 Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
316 if (Arg.isInvalid())
317 return SemaRef.ExprError();
318
319 Sema::OwningExprResult Result
320 = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
321 isSizeOf, E->getSourceRange());
322 if (Result.isInvalid())
323 return SemaRef.ExprError();
324
325 Arg.release();
326 return move(Result);
327}
328
329Sema::OwningExprResult
330TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
Douglas Gregorab452ba2009-03-26 23:50:42 +0000331 NestedNameSpecifier *NNS
332 = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
333 E->getQualifierRange(),
Douglas Gregor7e063902009-05-11 23:53:27 +0000334 TemplateArgs);
Douglas Gregorab452ba2009-03-26 23:50:42 +0000335 if (!NNS)
Douglas Gregoraa6af222009-03-25 00:27:28 +0000336 return SemaRef.ExprError();
337
Douglas Gregorab452ba2009-03-26 23:50:42 +0000338 CXXScopeSpec SS;
339 SS.setRange(E->getQualifierRange());
340 SS.setScopeRep(NNS);
341
Douglas Gregoraa6af222009-03-25 00:27:28 +0000342 // FIXME: We're passing in a NULL scope, because
343 // ActOnDeclarationNameExpr doesn't actually use the scope when we
344 // give it a non-empty scope specifier. Investigate whether it would
345 // be better to refactor ActOnDeclarationNameExpr.
346 return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
347 E->getDeclName(),
348 /*HasTrailingLParen=*/false,
349 &SS,
350 /*FIXME:isAddressOfOperand=*/false);
351}
352
353Sema::OwningExprResult
354TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
355 CXXTemporaryObjectExpr *E) {
356 QualType T = E->getType();
357 if (T->isDependentType()) {
Douglas Gregor7e063902009-05-11 23:53:27 +0000358 T = SemaRef.InstantiateType(T, TemplateArgs,
Douglas Gregoraa6af222009-03-25 00:27:28 +0000359 E->getTypeBeginLoc(), DeclarationName());
360 if (T.isNull())
361 return SemaRef.ExprError();
362 }
363
364 llvm::SmallVector<Expr *, 16> Args;
365 Args.reserve(E->getNumArgs());
366 bool Invalid = false;
367 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
368 ArgEnd = E->arg_end();
369 Arg != ArgEnd; ++Arg) {
370 OwningExprResult InstantiatedArg = Visit(*Arg);
371 if (InstantiatedArg.isInvalid()) {
372 Invalid = true;
373 break;
374 }
375
376 Args.push_back((Expr *)InstantiatedArg.release());
377 }
378
379 if (!Invalid) {
380 SourceLocation CommaLoc;
381 // FIXME: HACK!
382 if (Args.size() > 1)
383 CommaLoc
384 = SemaRef.PP.getLocForEndOfToken(Args[0]->getSourceRange().getEnd());
385 Sema::OwningExprResult Result(
386 SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
387 /*, FIXME*/),
388 T.getAsOpaquePtr(),
389 /*FIXME*/E->getTypeBeginLoc(),
390 Sema::MultiExprArg(SemaRef,
391 (void**)&Args[0],
392 Args.size()),
393 /*HACK*/&CommaLoc,
394 E->getSourceRange().getEnd()));
395 // At this point, Args no longer owns the arguments, no matter what.
396 return move(Result);
397 }
398
399 // Clean up the instantiated arguments.
400 // FIXME: Would rather do this with RAII.
401 for (unsigned Idx = 0; Idx < Args.size(); ++Idx)
402 SemaRef.DeleteExpr(Args[Idx]);
403
404 return SemaRef.ExprError();
405}
406
407Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
408 ImplicitCastExpr *E) {
409 assert(!E->isTypeDependent() && "Implicit casts must have known types");
410
411 Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
412 if (SubExpr.isInvalid())
413 return SemaRef.ExprError();
414
415 ImplicitCastExpr *ICE =
416 new (SemaRef.Context) ImplicitCastExpr(E->getType(),
417 (Expr *)SubExpr.release(),
418 E->isLvalueCast());
419 return SemaRef.Owned(ICE);
420}
421
Anders Carlsson0712d292009-05-15 20:26:03 +0000422Sema::OwningExprResult
423TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
424 QualType ThisType =
425 cast<CXXMethodDecl>(SemaRef.CurContext)->getThisType(SemaRef.Context);
426
427 CXXThisExpr *TE =
428 new (SemaRef.Context) CXXThisExpr(E->getLocStart(), ThisType);
429
430 return SemaRef.Owned(TE);
431}
432
Douglas Gregoraa6af222009-03-25 00:27:28 +0000433Sema::OwningExprResult
Douglas Gregor7e063902009-05-11 23:53:27 +0000434Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
Douglas Gregor50557a72009-05-15 20:47:12 +0000435 if (!E)
436 return Owned((Expr *)0);
437
Douglas Gregor7e063902009-05-11 23:53:27 +0000438 TemplateExprInstantiator Instantiator(*this, TemplateArgs);
Douglas Gregoraa6af222009-03-25 00:27:28 +0000439 return Instantiator.Visit(E);
440}