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