diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-08-11 05:31:07 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-08-11 05:31:07 +0000 |
commit | b98b1991c7ad1eaedb863bdbdd784ec164277675 (patch) | |
tree | bda94228daf1885ce26082a2be141dfdf9e417de /lib/Sema/SemaTemplateInstantiateExpr.cpp | |
parent | e955e7221a9cf335a089f548c01e854dca95ca99 (diff) |
Refactor the template-instantiation logic for expressions into a
generic tree transformation (also used for recanonicalization) and a
small amount of template-instantiation-specific logic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78645 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateExpr.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateExpr.cpp | 1377 |
1 files changed, 0 insertions, 1377 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp deleted file mode 100644 index 7a09210fe0..0000000000 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ /dev/null @@ -1,1377 +0,0 @@ -//===--- 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.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr( - UnresolvedFunctionNameExpr *E) { - return SemaRef.Owned(E->Retain()); -} - -Sema::OwningExprResult -TemplateExprInstantiator::VisitTemplateIdRefExpr(TemplateIdRefExpr *E) { - TemplateName Template - = SemaRef.InstantiateTemplateName(E->getTemplateName(), - E->getTemplateNameLoc(), - TemplateArgs); - // FIXME: Can InstantiateTemplateName report an error? - - llvm::SmallVector<TemplateArgument, 4> InstantiatedArgs; - for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) { - TemplateArgument InstArg = SemaRef.Instantiate(E->getTemplateArgs()[I], - TemplateArgs); - if (InstArg.isNull()) - return SemaRef.ExprError(); - - InstantiatedArgs.push_back(InstArg); - } - - // FIXME: It's possible that we'll find out now that the template name - // actually refers to a type, in which case this is a functional cast. - // Implement this! - - return SemaRef.BuildTemplateIdExpr(Template, E->getTemplateNameLoc(), - E->getLAngleLoc(), - InstantiatedArgs.data(), - InstantiatedArgs.size(), - E->getRAngleLoc()); -} - -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"); - - // If the corresponding template argument is NULL or non-existent, it's - // because we are performing instantiation from explicitly-specified - // template arguments in a function template, but there were some - // arguments left unspecified. - if (NTTP->getPosition() >= TemplateArgs.size() || - TemplateArgs[NTTP->getPosition()].isNull()) - return SemaRef.Owned(E->Retain()); - - const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()]; - - // The template argument itself might be an expression, in which - // case we just return that expression. - if (Arg.getKind() == TemplateArgument::Expression) - // FIXME: Clone the expression! - return SemaRef.Owned(Arg.getAsExpr()); - - if (Arg.getKind() == TemplateArgument::Declaration) { - ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl()); - - // FIXME: Can VD ever have a dependent type? - return SemaRef.BuildDeclRefExpr(VD, VD->getType(), E->getLocation(), - false, false); - } - - assert(Arg.getKind() == TemplateArgument::Integral); - 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())); - if (T->isBooleanType()) - return SemaRef.Owned(new (SemaRef.Context) CXXBoolLiteralExpr( - Arg.getAsIntegral()->getBoolValue(), - T, - E->getSourceRange().getBegin())); - - assert(Arg.getAsIntegral()->getBitWidth() == SemaRef.Context.getIntWidth(T)); - 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)); - } - - NamedDecl *InstD = SemaRef.InstantiateCurrentDeclRef(D); - if (!InstD) - return SemaRef.ExprError(); - - // FIXME: nested-name-specifier for QualifiedDeclRefExpr - return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD, - /*FIXME:*/false, - /*FIXME:*/0, - /*FIXME:*/false); -} - -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(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::VisitParenListExpr(ParenListExpr *E) { - ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef); - for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) { - OwningExprResult Init = Visit(E->getExpr(I)); - if (Init.isInvalid()) - return SemaRef.ExprError(); - Inits.push_back(Init.takeAs<Expr>()); - } - - return SemaRef.ActOnParenListExpr(E->getLParenLoc(), E->getRParenLoc(), - move_arg(Inits)); -} - -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"); - E->Retain(); - return SemaRef.Owned(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(SemaRef); - { - // C++0x [expr.sizeof]p1: - // The operand is either an expression, which is an unevaluated operand - // [...] - EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated); - - 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, - E->isAddressOfOperand()); -} - -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(), - E->getCastKind(), - (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(/*Scope=*/0, 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 |