summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaTemplateInstantiateExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateExpr.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp1278
1 files changed, 1278 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
new file mode 100644
index 0000000..a6b9703
--- /dev/null
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -0,0 +1,1278 @@
+//===--- SemaTemplateInstantiateExpr.cpp - C++ Template Expr Instantiation ===/
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===/
+//
+// This file implements C++ template instantiation for expressions.
+//
+//===----------------------------------------------------------------------===/
+#include "Sema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Designator.h"
+#include "clang/Lex/Preprocessor.h" // for the identifier table
+#include "llvm/Support/Compiler.h"
+using namespace clang;
+
+namespace {
+ class VISIBILITY_HIDDEN TemplateExprInstantiator
+ : public StmtVisitor<TemplateExprInstantiator, Sema::OwningExprResult> {
+ Sema &SemaRef;
+ const TemplateArgumentList &TemplateArgs;
+
+ public:
+ typedef Sema::OwningExprResult OwningExprResult;
+
+ TemplateExprInstantiator(Sema &SemaRef,
+ const TemplateArgumentList &TemplateArgs)
+ : SemaRef(SemaRef), TemplateArgs(TemplateArgs) { }
+
+ // Declare VisitXXXStmt nodes for all of the expression kinds.
+#define EXPR(Type, Base) OwningExprResult Visit##Type(Type *S);
+#define STMT(Type, Base)
+#include "clang/AST/StmtNodes.def"
+
+ // Base case. We can't get here.
+ Sema::OwningExprResult VisitStmt(Stmt *S) {
+ S->dump();
+ assert(false && "Cannot instantiate this kind of expression");
+ return SemaRef.ExprError();
+ }
+ };
+}
+
+// Base case. We can't get here.
+Sema::OwningExprResult TemplateExprInstantiator::VisitExpr(Expr *E) {
+ E->dump();
+ assert(false && "Cannot instantiate this kind of expression");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
+ UnresolvedFunctionNameExpr *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
+ NamedDecl *D = E->getDecl();
+ if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+ assert(NTTP->getDepth() == 0 && "No nested templates yet");
+ const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
+ QualType T = Arg.getIntegralType();
+ if (T->isCharType() || T->isWideCharType())
+ return SemaRef.Owned(new (SemaRef.Context) CharacterLiteral(
+ Arg.getAsIntegral()->getZExtValue(),
+ T->isWideCharType(),
+ T,
+ E->getSourceRange().getBegin()));
+ else if (T->isBooleanType())
+ return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr(
+ Arg.getAsIntegral()->getBoolValue(),
+ T,
+ E->getSourceRange().getBegin()));
+
+ return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
+ *Arg.getAsIntegral(),
+ T,
+ E->getSourceRange().getBegin()));
+ }
+
+ if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) {
+ // FIXME: instantiate each decl in the overload set
+ return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Ovl,
+ SemaRef.Context.OverloadTy,
+ E->getLocation(),
+ false, false));
+ }
+
+ ValueDecl *NewD
+ = dyn_cast_or_null<ValueDecl>(SemaRef.InstantiateCurrentDeclRef(D));
+ if (!NewD)
+ return SemaRef.ExprError();
+
+ // FIXME: Build QualifiedDeclRefExpr?
+ QualType T = NewD->getType();
+ return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
+ T.getNonReferenceType(),
+ E->getLocation(),
+ T->isDependentType(),
+ T->isDependentType()));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitParenExpr(ParenExpr *E) {
+ Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.Owned(new (SemaRef.Context) ParenExpr(
+ E->getLParen(), E->getRParen(),
+ (Expr *)SubExpr.release()));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
+ Sema::OwningExprResult Arg = Visit(E->getSubExpr());
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(),
+ E->getOpcode(),
+ move(Arg));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+ Sema::OwningExprResult LHS = Visit(E->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ Sema::OwningExprResult RHS = Visit(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ // Since the overloaded array-subscript operator (operator[]) can
+ // only be a member function, we can make several simplifying
+ // assumptions here:
+ // 1) Normal name lookup (from the current scope) will not ever
+ // find any declarations of operator[] that won't also be found be
+ // member operator lookup, so it is safe to pass a NULL Scope
+ // during the instantiation to avoid the lookup entirely.
+ //
+ // 2) Neither normal name lookup nor argument-dependent lookup at
+ // template definition time will find any operators that won't be
+ // found at template instantiation time, so we do not need to
+ // cache the results of name lookup as we do for the binary
+ // operators.
+ SourceLocation LLocFake = ((Expr*)LHS.get())->getSourceRange().getBegin();
+ return SemaRef.ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
+ /*FIXME:*/LLocFake,
+ move(RHS),
+ E->getRBracketLoc());
+}
+
+Sema::OwningExprResult TemplateExprInstantiator::VisitCallExpr(CallExpr *E) {
+ // Instantiate callee
+ OwningExprResult Callee = Visit(E->getCallee());
+ if (Callee.isInvalid())
+ return SemaRef.ExprError();
+
+ // Instantiate arguments
+ ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
+ for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
+ OwningExprResult Arg = Visit(E->getArg(I));
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ FakeCommaLocs.push_back(
+ SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
+ Args.push_back(Arg.takeAs<Expr>());
+ }
+
+ SourceLocation FakeLParenLoc
+ = ((Expr *)Callee.get())->getSourceRange().getBegin();
+ return SemaRef.ActOnCallExpr(/*Scope=*/0, move(Callee),
+ /*FIXME:*/FakeLParenLoc,
+ move_arg(Args),
+ /*FIXME:*/&FakeCommaLocs.front(),
+ E->getRParenLoc());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitMemberExpr(MemberExpr *E) {
+ // Instantiate the base of the expression.
+ OwningExprResult Base = Visit(E->getBase());
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ // FIXME: Handle declaration names here
+ SourceLocation FakeOperatorLoc =
+ SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
+ return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
+ move(Base),
+ /*FIXME*/FakeOperatorLoc,
+ E->isArrow()? tok::arrow
+ : tok::period,
+ E->getMemberLoc(),
+ /*FIXME:*/*E->getMemberDecl()->getIdentifier(),
+ /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+ SourceLocation FakeTypeLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
+ QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
+ FakeTypeLoc,
+ DeclarationName());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ OwningExprResult Init = Visit(E->getInitializer());
+ if (Init.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnCompoundLiteral(E->getLParenLoc(),
+ T.getAsOpaquePtr(),
+ /*FIXME*/E->getLParenLoc(),
+ move(Init));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
+ Sema::OwningExprResult LHS = Visit(E->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ Sema::OwningExprResult RHS = Visit(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ Sema::OwningExprResult Result
+ = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(),
+ E->getOpcode(),
+ (Expr *)LHS.get(),
+ (Expr *)RHS.get());
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ LHS.release();
+ RHS.release();
+ return move(Result);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCompoundAssignOperator(
+ CompoundAssignOperator *E) {
+ return VisitBinaryOperator(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ Sema::OwningExprResult First = Visit(E->getArg(0));
+ if (First.isInvalid())
+ return SemaRef.ExprError();
+
+ Expr *Args[2] = { (Expr *)First.get(), 0 };
+
+ Sema::OwningExprResult Second(SemaRef);
+ if (E->getNumArgs() == 2) {
+ Second = Visit(E->getArg(1));
+
+ if (Second.isInvalid())
+ return SemaRef.ExprError();
+
+ Args[1] = (Expr *)Second.get();
+ }
+
+ if (!E->isTypeDependent()) {
+ // Since our original expression was not type-dependent, we do not
+ // perform lookup again at instantiation time (C++ [temp.dep]p1).
+ // Instead, we just build the new overloaded operator call
+ // expression.
+ OwningExprResult Callee = Visit(E->getCallee());
+ if (Callee.isInvalid())
+ return SemaRef.ExprError();
+
+ First.release();
+ Second.release();
+
+ return SemaRef.Owned(new (SemaRef.Context) CXXOperatorCallExpr(
+ SemaRef.Context,
+ E->getOperator(),
+ Callee.takeAs<Expr>(),
+ Args, E->getNumArgs(),
+ E->getType(),
+ E->getOperatorLoc()));
+ }
+
+ bool isPostIncDec = E->getNumArgs() == 2 &&
+ (E->getOperator() == OO_PlusPlus || E->getOperator() == OO_MinusMinus);
+ if (E->getNumArgs() == 1 || isPostIncDec) {
+ if (!Args[0]->getType()->isOverloadableType()) {
+ // The argument is not of overloadable type, so try to create a
+ // built-in unary operation.
+ UnaryOperator::Opcode Opc
+ = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
+
+ return SemaRef.CreateBuiltinUnaryOp(E->getOperatorLoc(), Opc,
+ move(First));
+ }
+
+ // Fall through to perform overload resolution
+ } else {
+ assert(E->getNumArgs() == 2 && "Expected binary operation");
+
+ Sema::OwningExprResult Result(SemaRef);
+ if (!Args[0]->getType()->isOverloadableType() &&
+ !Args[1]->getType()->isOverloadableType()) {
+ // Neither of the arguments is an overloadable type, so try to
+ // create a built-in binary operation.
+ BinaryOperator::Opcode Opc =
+ BinaryOperator::getOverloadedOpcode(E->getOperator());
+ Result = SemaRef.CreateBuiltinBinOp(E->getOperatorLoc(), Opc,
+ Args[0], Args[1]);
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ First.release();
+ Second.release();
+ return move(Result);
+ }
+
+ // Fall through to perform overload resolution.
+ }
+
+ // Compute the set of functions that were found at template
+ // definition time.
+ Sema::FunctionSet Functions;
+ DeclRefExpr *DRE = cast<DeclRefExpr>(E->getCallee());
+ OverloadedFunctionDecl *Overloads
+ = cast<OverloadedFunctionDecl>(DRE->getDecl());
+
+ // FIXME: Do we have to check
+ // IsAcceptableNonMemberOperatorCandidate for each of these?
+ for (OverloadedFunctionDecl::function_iterator
+ F = Overloads->function_begin(),
+ FEnd = Overloads->function_end();
+ F != FEnd; ++F)
+ Functions.insert(*F);
+
+ // Add any functions found via argument-dependent lookup.
+ DeclarationName OpName
+ = SemaRef.Context.DeclarationNames.getCXXOperatorName(E->getOperator());
+ SemaRef.ArgumentDependentLookup(OpName, Args, E->getNumArgs(), Functions);
+
+ // Create the overloaded operator invocation.
+ if (E->getNumArgs() == 1 || isPostIncDec) {
+ UnaryOperator::Opcode Opc
+ = UnaryOperator::getOverloadedOpcode(E->getOperator(), isPostIncDec);
+ return SemaRef.CreateOverloadedUnaryOp(E->getOperatorLoc(), Opc,
+ Functions, move(First));
+ }
+
+ // FIXME: This would be far less ugly if CreateOverloadedBinOp took in ExprArg
+ // arguments!
+ BinaryOperator::Opcode Opc =
+ BinaryOperator::getOverloadedOpcode(E->getOperator());
+ OwningExprResult Result
+ = SemaRef.CreateOverloadedBinOp(E->getOperatorLoc(), Opc,
+ Functions, Args[0], Args[1]);
+
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ First.release();
+ Second.release();
+ return move(Result);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
+ VarDecl *Var
+ = cast_or_null<VarDecl>(SemaRef.InstantiateDecl(E->getVarDecl(),
+ SemaRef.CurContext,
+ TemplateArgs));
+ if (!Var)
+ return SemaRef.ExprError();
+
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(E->getVarDecl(), Var);
+ return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(
+ E->getStartLoc(),
+ SourceLocation(),
+ Var));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {
+ Sema::OwningExprResult Cond = Visit(E->getCond());
+ if (Cond.isInvalid())
+ return SemaRef.ExprError();
+
+ Sema::OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(),
+ TemplateArgs);
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ Sema::OwningExprResult RHS = Visit(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!E->isTypeDependent()) {
+ // Since our original expression was not type-dependent, we do not
+ // perform lookup again at instantiation time (C++ [temp.dep]p1).
+ // Instead, we just build the new conditional operator call expression.
+ return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(
+ Cond.takeAs<Expr>(),
+ LHS.takeAs<Expr>(),
+ RHS.takeAs<Expr>(),
+ E->getType()));
+ }
+
+
+ return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),
+ /*FIXME*/E->getFalseExpr()->getLocStart(),
+ move(Cond), move(LHS), move(RHS));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitAddrLabelExpr(AddrLabelExpr *E) {
+ return SemaRef.ActOnAddrLabel(E->getAmpAmpLoc(),
+ E->getLabelLoc(),
+ E->getLabel()->getID());
+}
+
+Sema::OwningExprResult TemplateExprInstantiator::VisitStmtExpr(StmtExpr *E) {
+ Sema::OwningStmtResult SubStmt
+ = SemaRef.InstantiateCompoundStmt(E->getSubStmt(), TemplateArgs, true);
+ if (SubStmt.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnStmtExpr(E->getLParenLoc(), move(SubStmt),
+ E->getRParenLoc());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
+ assert(false && "__builtin_types_compatible_p is not legal in C++");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
+ ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
+ for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
+ OwningExprResult SubExpr = Visit(E->getExpr(I));
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ SubExprs.push_back(SubExpr.takeAs<Expr>());
+ }
+
+ // Find the declaration for __builtin_shufflevector
+ const IdentifierInfo &Name
+ = SemaRef.Context.Idents.get("__builtin_shufflevector");
+ TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
+ DeclContext::lookup_result Lookup
+ = TUDecl->lookup(SemaRef.Context, DeclarationName(&Name));
+ assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
+
+ // Build a reference to the __builtin_shufflevector builtin
+ FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
+ Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
+ E->getBuiltinLoc(),
+ false, false);
+ SemaRef.UsualUnaryConversions(Callee);
+
+ // Build the CallExpr
+ CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
+ SubExprs.takeAs<Expr>(),
+ SubExprs.size(),
+ Builtin->getResultType(),
+ E->getRParenLoc());
+ OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
+
+ // Type-check the __builtin_shufflevector expression.
+ OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ OwnedCall.release();
+ return move(Result);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitChooseExpr(ChooseExpr *E) {
+ OwningExprResult Cond = Visit(E->getCond());
+ if (Cond.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(), TemplateArgs);
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult RHS = Visit(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnChooseExpr(E->getBuiltinLoc(),
+ move(Cond), move(LHS), move(RHS),
+ E->getRParenLoc());
+}
+
+Sema::OwningExprResult TemplateExprInstantiator::VisitVAArgExpr(VAArgExpr *E) {
+ OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ SourceLocation FakeTypeLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getSubExpr()->getSourceRange()
+ .getEnd());
+ QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
+ /*FIXME:*/FakeTypeLoc,
+ DeclarationName());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnVAArg(E->getBuiltinLoc(), move(SubExpr),
+ T.getAsOpaquePtr(), E->getRParenLoc());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitInitListExpr(InitListExpr *E) {
+ ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+ for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
+ OwningExprResult Init = Visit(E->getInit(I));
+ if (Init.isInvalid())
+ return SemaRef.ExprError();
+ Inits.push_back(Init.takeAs<Expr>());
+ }
+
+ return SemaRef.ActOnInitList(E->getLBraceLoc(), move_arg(Inits),
+ E->getRBraceLoc());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+ Designation Desig;
+
+ // Instantiate the initializer value
+ OwningExprResult Init = Visit(E->getInit());
+ if (Init.isInvalid())
+ return SemaRef.ExprError();
+
+ // Instantiate the designators.
+ ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
+ for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
+ DEnd = E->designators_end();
+ D != DEnd; ++D) {
+ if (D->isFieldDesignator()) {
+ Desig.AddDesignator(Designator::getField(D->getFieldName(),
+ D->getDotLoc(),
+ D->getFieldLoc()));
+ continue;
+ }
+
+ if (D->isArrayDesignator()) {
+ OwningExprResult Index = Visit(E->getArrayIndex(*D));
+ if (Index.isInvalid())
+ return SemaRef.ExprError();
+
+ Desig.AddDesignator(Designator::getArray(Index.get(),
+ D->getLBracketLoc()));
+
+ ArrayExprs.push_back(Index.release());
+ continue;
+ }
+
+ assert(D->isArrayRangeDesignator() && "New kind of designator?");
+ OwningExprResult Start = Visit(E->getArrayRangeStart(*D));
+ if (Start.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult End = Visit(E->getArrayRangeEnd(*D));
+ if (End.isInvalid())
+ return SemaRef.ExprError();
+
+ Desig.AddDesignator(Designator::getArrayRange(Start.get(),
+ End.get(),
+ D->getLBracketLoc(),
+ D->getEllipsisLoc()));
+
+ ArrayExprs.push_back(Start.release());
+ ArrayExprs.push_back(End.release());
+ }
+
+ OwningExprResult Result =
+ SemaRef.ActOnDesignatedInitializer(Desig,
+ E->getEqualOrColonLoc(),
+ E->usesGNUSyntax(),
+ move(Init));
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ ArrayExprs.take();
+ return move(Result);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitImplicitValueInitExpr(
+ ImplicitValueInitExpr *E) {
+ assert(!E->isTypeDependent() && !E->isValueDependent() &&
+ "ImplicitValueInitExprs are never dependent");
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
+ OwningExprResult Base = Visit(E->getBase());
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ SourceLocation FakeOperatorLoc =
+ SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
+ return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
+ move(Base),
+ /*FIXME*/FakeOperatorLoc,
+ tok::period,
+ E->getAccessorLoc(),
+ E->getAccessor(),
+ /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitBlockExpr(BlockExpr *E) {
+ assert(false && "FIXME:Template instantiation for blocks is unimplemented");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+ assert(false && "FIXME:Template instantiation for blocks is unimplemented");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+ bool isSizeOf = E->isSizeOf();
+
+ if (E->isArgumentType()) {
+ QualType T = E->getArgumentType();
+ if (T->isDependentType()) {
+ T = SemaRef.InstantiateType(T, TemplateArgs,
+ /*FIXME*/E->getOperatorLoc(),
+ &SemaRef.PP.getIdentifierTable().get("sizeof"));
+ if (T.isNull())
+ return SemaRef.ExprError();
+ }
+
+ return SemaRef.CreateSizeOfAlignOfExpr(T, E->getOperatorLoc(), isSizeOf,
+ E->getSourceRange());
+ }
+
+ Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ Sema::OwningExprResult Result
+ = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
+ isSizeOf, E->getSourceRange());
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ Arg.release();
+ return move(Result);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
+ NestedNameSpecifier *NNS
+ = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange(),
+ TemplateArgs);
+ if (!NNS)
+ return SemaRef.ExprError();
+
+ CXXScopeSpec SS;
+ SS.setRange(E->getQualifierRange());
+ SS.setScopeRep(NNS);
+
+ // FIXME: We're passing in a NULL scope, because
+ // ActOnDeclarationNameExpr doesn't actually use the scope when we
+ // give it a non-empty scope specifier. Investigate whether it would
+ // be better to refactor ActOnDeclarationNameExpr.
+ return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0, E->getLocation(),
+ E->getDeclName(),
+ /*HasTrailingLParen=*/false,
+ &SS,
+ /*FIXME:isAddressOfOperand=*/false);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
+ CXXTemporaryObjectExpr *E) {
+ QualType T = E->getType();
+ if (T->isDependentType()) {
+ T = SemaRef.InstantiateType(T, TemplateArgs,
+ E->getTypeBeginLoc(), DeclarationName());
+ if (T.isNull())
+ return SemaRef.ExprError();
+ }
+
+ ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ Args.reserve(E->getNumArgs());
+ for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
+ ArgEnd = E->arg_end();
+ Arg != ArgEnd; ++Arg) {
+ OwningExprResult InstantiatedArg = Visit(*Arg);
+ if (InstantiatedArg.isInvalid())
+ return SemaRef.ExprError();
+
+ Args.push_back((Expr *)InstantiatedArg.release());
+ }
+
+ SourceLocation CommaLoc;
+ // FIXME: HACK!
+ if (Args.size() > 1) {
+ Expr *First = (Expr *)Args[0];
+ CommaLoc
+ = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
+ }
+ return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()
+ /*, FIXME*/),
+ T.getAsOpaquePtr(),
+ /*FIXME*/E->getTypeBeginLoc(),
+ move_arg(Args),
+ /*HACK*/&CommaLoc,
+ E->getSourceRange().getEnd());
+}
+
+Sema::OwningExprResult TemplateExprInstantiator::VisitCastExpr(CastExpr *E) {
+ assert(false && "Cannot instantiate abstract CastExpr");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
+ ImplicitCastExpr *E) {
+ assert(!E->isTypeDependent() && "Implicit casts must have known types");
+
+ Sema::OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ ImplicitCastExpr *ICE =
+ new (SemaRef.Context) ImplicitCastExpr(E->getType(),
+ (Expr *)SubExpr.release(),
+ E->isLvalueCast());
+ return SemaRef.Owned(ICE);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+ assert(false && "Cannot instantiate abstract ExplicitCastExpr");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCStyleCastExpr(CStyleCastExpr *E) {
+ // Instantiate the type that we're casting to.
+ SourceLocation TypeStartLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
+ QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
+ TemplateArgs,
+ TypeStartLoc,
+ DeclarationName());
+ if (ExplicitTy.isNull())
+ return SemaRef.ExprError();
+
+ // Instantiate the subexpression.
+ OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnCastExpr(E->getLParenLoc(),
+ ExplicitTy.getAsOpaquePtr(),
+ E->getRParenLoc(),
+ move(SubExpr));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+ return VisitCallExpr(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+ // Figure out which cast operator we're dealing with.
+ tok::TokenKind Kind;
+ switch (E->getStmtClass()) {
+ case Stmt::CXXStaticCastExprClass:
+ Kind = tok::kw_static_cast;
+ break;
+
+ case Stmt::CXXDynamicCastExprClass:
+ Kind = tok::kw_dynamic_cast;
+ break;
+
+ case Stmt::CXXReinterpretCastExprClass:
+ Kind = tok::kw_reinterpret_cast;
+ break;
+
+ case Stmt::CXXConstCastExprClass:
+ Kind = tok::kw_const_cast;
+ break;
+
+ default:
+ assert(false && "Invalid C++ named cast");
+ return SemaRef.ExprError();
+ }
+
+ // Instantiate the type that we're casting to.
+ SourceLocation TypeStartLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
+ QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
+ TemplateArgs,
+ TypeStartLoc,
+ DeclarationName());
+ if (ExplicitTy.isNull())
+ return SemaRef.ExprError();
+
+ // Instantiate the subexpression.
+ OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ SourceLocation FakeLAngleLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
+ SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
+ SourceLocation FakeRParenLoc
+ = SemaRef.PP.getLocForEndOfToken(
+ E->getSubExpr()->getSourceRange().getEnd());
+ return SemaRef.ActOnCXXNamedCast(E->getOperatorLoc(), Kind,
+ /*FIXME:*/FakeLAngleLoc,
+ ExplicitTy.getAsOpaquePtr(),
+ /*FIXME:*/FakeRAngleLoc,
+ /*FIXME:*/FakeRAngleLoc,
+ move(SubExpr),
+ /*FIXME:*/FakeRParenLoc);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
+ return VisitCXXNamedCastExpr(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+ return VisitCXXNamedCastExpr(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXReinterpretCastExpr(
+ CXXReinterpretCastExpr *E) {
+ return VisitCXXNamedCastExpr(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
+ return VisitCXXNamedCastExpr(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXThisExpr(CXXThisExpr *E) {
+ QualType ThisType =
+ cast<CXXMethodDecl>(SemaRef.CurContext)->getThisType(SemaRef.Context);
+
+ CXXThisExpr *TE =
+ new (SemaRef.Context) CXXThisExpr(E->getLocStart(), ThisType);
+
+ return SemaRef.Owned(TE);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+ if (E->isTypeOperand()) {
+ QualType T = SemaRef.InstantiateType(E->getTypeOperand(),
+ TemplateArgs,
+ /*FIXME*/E->getSourceRange().getBegin(),
+ DeclarationName());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnCXXTypeid(E->getSourceRange().getBegin(),
+ /*FIXME*/E->getSourceRange().getBegin(),
+ true, T.getAsOpaquePtr(),
+ E->getSourceRange().getEnd());
+ }
+
+ OwningExprResult Operand = Visit(E->getExprOperand());
+ if (Operand.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult Result
+ = SemaRef.ActOnCXXTypeid(E->getSourceRange().getBegin(),
+ /*FIXME*/E->getSourceRange().getBegin(),
+ false, Operand.get(),
+ E->getSourceRange().getEnd());
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
+ return move(Result);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXThrowExpr(CXXThrowExpr *E) {
+ OwningExprResult SubExpr(SemaRef, (void *)0);
+ if (E->getSubExpr()) {
+ SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+ }
+
+ return SemaRef.ActOnCXXThrow(E->getThrowLoc(), move(SubExpr));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+ assert(false &&
+ "FIXME: Instantiation for default arguments is unimplemented");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXBindTemporaryExpr(
+ CXXBindTemporaryExpr *E) {
+ OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXConstructExpr(CXXConstructExpr *E) {
+ assert(!cast<CXXRecordDecl>(E->getConstructor()->getDeclContext())
+ ->isDependentType() && "Dependent constructor shouldn't be here");
+
+ QualType T = SemaRef.InstantiateType(E->getType(), TemplateArgs,
+ /*FIXME*/E->getSourceRange().getBegin(),
+ DeclarationName());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
+ ArgEnd = E->arg_end();
+ Arg != ArgEnd; ++Arg) {
+ OwningExprResult ArgInst = Visit(*Arg);
+ if (ArgInst.isInvalid())
+ return SemaRef.ExprError();
+
+ Args.push_back(ArgInst.takeAs<Expr>());
+ }
+
+ return SemaRef.Owned(CXXConstructExpr::Create(SemaRef.Context, T,
+ E->getConstructor(),
+ E->isElidable(),
+ Args.takeAs<Expr>(),
+ Args.size()));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXFunctionalCastExpr(
+ CXXFunctionalCastExpr *E) {
+ // Instantiate the type that we're casting to.
+ QualType ExplicitTy = SemaRef.InstantiateType(E->getTypeAsWritten(),
+ TemplateArgs,
+ E->getTypeBeginLoc(),
+ DeclarationName());
+ if (ExplicitTy.isNull())
+ return SemaRef.ExprError();
+
+ // Instantiate the subexpression.
+ OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ // FIXME: The end of the type's source range is wrong
+ Expr *Sub = SubExpr.takeAs<Expr>();
+ return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc()),
+ ExplicitTy.getAsOpaquePtr(),
+ /*FIXME:*/E->getTypeBeginLoc(),
+ Sema::MultiExprArg(SemaRef,
+ (void **)&Sub,
+ 1),
+ 0,
+ E->getRParenLoc());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+ return SemaRef.Clone(E);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXNewExpr(CXXNewExpr *E) {
+ // Instantiate the type that we're allocating
+ QualType AllocType = SemaRef.InstantiateType(E->getAllocatedType(),
+ TemplateArgs,
+ /*FIXME:*/E->getSourceRange().getBegin(),
+ DeclarationName());
+ if (AllocType.isNull())
+ return SemaRef.ExprError();
+
+ // Instantiate the size of the array we're allocating (if any).
+ OwningExprResult ArraySize = SemaRef.InstantiateExpr(E->getArraySize(),
+ TemplateArgs);
+ if (ArraySize.isInvalid())
+ return SemaRef.ExprError();
+
+ // Instantiate the placement arguments (if any).
+ ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
+ for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
+ OwningExprResult Arg = Visit(E->getPlacementArg(I));
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ PlacementArgs.push_back(Arg.take());
+ }
+
+ // Instantiate the constructor arguments (if any).
+ ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
+ for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
+ OwningExprResult Arg = Visit(E->getConstructorArg(I));
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ ConstructorArgs.push_back(Arg.take());
+ }
+
+ return SemaRef.BuildCXXNew(E->getSourceRange().getBegin(),
+ E->isGlobalNew(),
+ /*FIXME*/SourceLocation(),
+ move_arg(PlacementArgs),
+ /*FIXME*/SourceLocation(),
+ E->isParenTypeId(),
+ AllocType,
+ /*FIXME*/E->getSourceRange().getBegin(),
+ SourceRange(),
+ move(ArraySize),
+ /*FIXME*/SourceLocation(),
+ Sema::MultiExprArg(SemaRef,
+ ConstructorArgs.take(),
+ ConstructorArgs.size()),
+ E->getSourceRange().getEnd());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+ OwningExprResult Operand = Visit(E->getArgument());
+ if (Operand.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnCXXDelete(E->getSourceRange().getBegin(),
+ E->isGlobalDelete(),
+ E->isArrayForm(),
+ move(Operand));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+ QualType T = SemaRef.InstantiateType(E->getQueriedType(), TemplateArgs,
+ /*FIXME*/E->getSourceRange().getBegin(),
+ DeclarationName());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ SourceLocation FakeLParenLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getSourceRange().getBegin());
+ return SemaRef.ActOnUnaryTypeTrait(E->getTrait(),
+ E->getSourceRange().getBegin(),
+ /*FIXME*/FakeLParenLoc,
+ T.getAsOpaquePtr(),
+ E->getSourceRange().getEnd());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
+ NestedNameSpecifier *NNS
+ = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange(),
+ TemplateArgs);
+ if (!NNS)
+ return SemaRef.ExprError();
+
+ CXXScopeSpec SS;
+ SS.setRange(E->getQualifierRange());
+ SS.setScopeRep(NNS);
+ return SemaRef.ActOnDeclarationNameExpr(/*Scope=*/0,
+ E->getLocation(),
+ E->getDecl()->getDeclName(),
+ /*Trailing lparen=*/false,
+ &SS,
+ /*FIXME:*/false);
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXExprWithTemporaries(
+ CXXExprWithTemporaries *E) {
+ OwningExprResult SubExpr = Visit(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnFinishFullExpr(move(SubExpr));
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXUnresolvedConstructExpr(
+ CXXUnresolvedConstructExpr *E) {
+ QualType T = SemaRef.InstantiateType(E->getTypeAsWritten(), TemplateArgs,
+ E->getTypeBeginLoc(),
+ DeclarationName());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
+ for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
+ ArgEnd = E->arg_end();
+ Arg != ArgEnd; ++Arg) {
+ OwningExprResult InstArg = Visit(*Arg);
+ if (InstArg.isInvalid())
+ return SemaRef.ExprError();
+
+ FakeCommaLocs.push_back(
+ SemaRef.PP.getLocForEndOfToken((*Arg)->getSourceRange().getEnd()));
+ Args.push_back(InstArg.takeAs<Expr>());
+ }
+
+ // FIXME: The end of the type range isn't exactly correct.
+ // FIXME: we're faking the locations of the commas
+ return SemaRef.ActOnCXXTypeConstructExpr(SourceRange(E->getTypeBeginLoc(),
+ E->getLParenLoc()),
+ T.getAsOpaquePtr(),
+ E->getLParenLoc(),
+ move_arg(Args),
+ &FakeCommaLocs.front(),
+ E->getRParenLoc());
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitCXXUnresolvedMemberExpr(
+ CXXUnresolvedMemberExpr *E) {
+ // Instantiate the base of the expression.
+ OwningExprResult Base = Visit(E->getBase());
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ // FIXME: Instantiate the declaration name.
+ return SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
+ move(Base), E->getOperatorLoc(),
+ E->isArrow()? tok::arrow
+ : tok::period,
+ E->getMemberLoc(),
+ /*FIXME:*/*E->getMember().getAsIdentifierInfo(),
+ /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+}
+
+//----------------------------------------------------------------------------
+// Objective-C Expressions
+//----------------------------------------------------------------------------
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+TemplateExprInstantiator::VisitObjCSuperExpr(ObjCSuperExpr *E) {
+ assert(false && "FIXME: Template instantiations for ObjC expressions");
+ return SemaRef.ExprError();
+}
+
+Sema::OwningExprResult
+Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
+ if (!E)
+ return Owned((Expr *)0);
+
+ TemplateExprInstantiator Instantiator(*this, TemplateArgs);
+ return Instantiator.Visit(E);
+}
OpenPOWER on IntegriCloud