[cfe-commits] r78645 - in /cfe/trunk: include/clang/AST/StmtNodes.def lib/Sema/CMakeLists.txt lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp lib/Sema/TreeTransform.h
Douglas Gregor
dgregor at apple.com
Mon Aug 10 22:31:07 PDT 2009
Author: dgregor
Date: Tue Aug 11 00:31:07 2009
New Revision: 78645
URL: http://llvm.org/viewvc/llvm-project?rev=78645&view=rev
Log:
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.
Removed:
cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
Modified:
cfe/trunk/include/clang/AST/StmtNodes.def
cfe/trunk/lib/Sema/CMakeLists.txt
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/TreeTransform.h
Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=78645&r1=78644&r2=78645&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Tue Aug 11 00:31:07 2009
@@ -25,6 +25,10 @@
# define EXPR(Type, Base) STMT(Type, Base)
#endif
+#ifndef ABSTRACT_EXPR
+# define ABSTRACT_EXPR(Type, Base) EXPR(Type, Base)
+#endif
+
// Normal Statements.
STMT(NullStmt , Stmt)
FIRST_STMT(NullStmt)
@@ -64,7 +68,7 @@
LAST_STMT(CXXTryStmt)
// Expressions.
-EXPR(Expr , Stmt)
+ABSTRACT_EXPR(Expr , Stmt)
FIRST_EXPR(Expr)
EXPR(PredefinedExpr , Expr)
EXPR(DeclRefExpr , Expr)
@@ -151,8 +155,9 @@
LAST_EXPR(BlockDeclRefExpr)
-#undef STMT
+#undef ABSTRACT_EXPR
#undef EXPR
+#undef STMT
#undef FIRST_STMT
#undef LAST_STMT
#undef FIRST_EXPR
Modified: cfe/trunk/lib/Sema/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CMakeLists.txt?rev=78645&r1=78644&r2=78645&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CMakeLists.txt (original)
+++ cfe/trunk/lib/Sema/CMakeLists.txt Tue Aug 11 00:31:07 2009
@@ -26,7 +26,6 @@
SemaTemplateDeduction.cpp
SemaTemplateInstantiate.cpp
SemaTemplateInstantiateDecl.cpp
- SemaTemplateInstantiateExpr.cpp
SemaTemplateInstantiateStmt.cpp
SemaType.cpp
)
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=78645&r1=78644&r2=78645&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Aug 11 00:31:07 2009
@@ -316,24 +316,30 @@
/// \brief Returns the name of the entity being instantiated, if any.
DeclarationName getBaseEntity() { return Entity; }
- /// \brief Transforms an expression by instantiating it with the given
- /// template arguments.
- Sema::OwningExprResult TransformExpr(Expr *E);
-
/// \brief Transform the given declaration by instantiating a reference to
/// this declaration.
Decl *TransformDecl(Decl *D);
+ Sema::OwningStmtResult TransformStmt(Stmt *S) {
+ return SemaRef.InstantiateStmt(S, TemplateArgs);
+ }
+
+ Sema::OwningStmtResult TransformCompoundStmt(CompoundStmt *S,
+ bool IsStmtExpr) {
+ return SemaRef.InstantiateCompoundStmt(S, TemplateArgs, IsStmtExpr);
+ }
+
+ Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
+
+ Sema::OwningExprResult
+ TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E);
+
/// \brief Transforms a template type parameter type by performing
/// substitution of the corresponding template type argument.
QualType TransformTemplateTypeParmType(const TemplateTypeParmType *T);
};
}
-Sema::OwningExprResult TemplateInstantiator::TransformExpr(Expr *E) {
- return getSema().InstantiateExpr(E, TemplateArgs);
-}
-
Decl *TemplateInstantiator::TransformDecl(Decl *D) {
if (TemplateTemplateParmDecl *TTP
= dyn_cast_or_null<TemplateTemplateParmDecl>(D)) {
@@ -351,6 +357,93 @@
return SemaRef.InstantiateCurrentDeclRef(cast_or_null<NamedDecl>(D));
}
+Sema::OwningExprResult
+TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
+ // FIXME: Clean this up a bit
+ 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); // FIXME: Clone the expression!
+
+ 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
+TemplateInstantiator::TransformCXXConditionDeclExpr(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));
+}
+
QualType
TemplateInstantiator::TransformTemplateTypeParmType(
const TemplateTypeParmType *T) {
@@ -711,6 +804,17 @@
ClassTemplateSpec->getTemplateArgs());
}
+Sema::OwningExprResult
+Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
+ if (!E)
+ return Owned(E);
+
+ TemplateInstantiator Instantiator(*this, TemplateArgs,
+ SourceLocation(),
+ DeclarationName());
+ return Instantiator.TransformExpr(E);
+}
+
/// \brief Instantiate a nested-name-specifier.
NestedNameSpecifier *
Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
Removed: cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp?rev=78644&view=auto
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (removed)
@@ -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
- = 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());
- }
-
- // We don't know whether the expression is potentially evaluated until
- // after we perform semantic analysis, so the expression is potentially
- // potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef,
- Action::PotentiallyPotentiallyEvaluated);
-
- 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(SemaRef.BuildCXXConstructExpr(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.Owned(E->Retain());
-}
-
-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();
-
- Expr *Temp =
- SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
- E->shouldDestroyTemporaries());
- return SemaRef.Owned(Temp);
-}
-
-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();
-
- tok::TokenKind OpKind = E->isArrow() ? tok::arrow : tok::period;
- CXXScopeSpec SS;
- Base = SemaRef.ActOnCXXEnterMemberScope(0, SS, move(Base), OpKind);
- // FIXME: Instantiate the declaration name.
- Base = SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
- move(Base), E->getOperatorLoc(),
- OpKind,
- E->getMemberLoc(),
- /*FIXME:*/*E->getMember().getAsIdentifierInfo(),
- /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
- SemaRef.ActOnCXXExitMemberScope(0, SS);
- return move(Base);
-}
-
-//----------------------------------------------------------------------------
-// Objective-C Expressions
-//----------------------------------------------------------------------------
-Sema::OwningExprResult
-TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) {
- return SemaRef.Owned(E->Retain());
-}
-
-Sema::OwningExprResult
-TemplateExprInstantiator::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
- QualType EncodedType = SemaRef.InstantiateType(E->getEncodedType(),
- TemplateArgs,
- /*FIXME:*/E->getAtLoc(),
- DeclarationName());
- if (EncodedType.isNull())
- return SemaRef.ExprError();
-
- return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(E->getAtLoc(),
- EncodedType,
- E->getRParenLoc()));
-}
-
-Sema::OwningExprResult
-TemplateExprInstantiator::VisitObjCMessageExpr(ObjCMessageExpr *E) {
- assert(false && "FIXME: Template instantiations for ObjC expressions");
- return SemaRef.ExprError();
-}
-
-Sema::OwningExprResult
-TemplateExprInstantiator::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
- return SemaRef.Owned(E->Retain());
-}
-
-Sema::OwningExprResult
-TemplateExprInstantiator::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
- return SemaRef.Owned(E->Retain());
-}
-
-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
-TemplateExprInstantiator::VisitObjCIsaExpr(ObjCIsaExpr *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);
-}
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=78645&r1=78644&r2=78645&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Aug 11 00:31:07 2009
@@ -16,6 +16,11 @@
#include "Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/Parse/Ownership.h"
+#include "clang/Parse/Designator.h"
+#include "clang/Lex/Preprocessor.h"
#include <algorithm>
namespace clang {
@@ -80,6 +85,12 @@
Sema &SemaRef;
public:
+ typedef Sema::OwningStmtResult OwningStmtResult;
+ typedef Sema::OwningExprResult OwningExprResult;
+ typedef Sema::StmtArg StmtArg;
+ typedef Sema::ExprArg ExprArg;
+ typedef Sema::MultiExprArg MultiExprArg;
+
/// \brief Initializes a new tree transformer.
TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
@@ -117,6 +128,34 @@
/// implementation with a more precise name.
DeclarationName getBaseEntity() { return DeclarationName(); }
+ /// \brief Sets the "base" location and entity when that
+ /// information is known based on another transformation.
+ ///
+ /// By default, the source location and entity are ignored. Subclasses can
+ /// override this function to provide a customized implementation.
+ void setBase(SourceLocation Loc, DeclarationName Entity) { }
+
+ /// \brief RAII object that temporarily sets the base location and entity
+ /// used for reporting diagnostics in types.
+ class TemporaryBase {
+ TreeTransform &Self;
+ SourceLocation OldLocation;
+ DeclarationName OldEntity;
+
+ public:
+ TemporaryBase(TreeTransform &Self, SourceLocation Location,
+ DeclarationName Entity) : Self(Self)
+ {
+ OldLocation = Self.getDerived().getBaseLocation();
+ OldEntity = Self.getDerived().getBaseEntity();
+ Self.getDerived().setBase(Location, Entity);
+ }
+
+ ~TemporaryBase() {
+ Self.getDerived().setBase(OldLocation, OldEntity);
+ }
+ };
+
/// \brief Determine whether the given type \p T has already been
/// transformed.
///
@@ -153,14 +192,29 @@
/// \brief Transform the given statement.
///
/// FIXME: At the moment, subclasses must override this.
- Sema::OwningStmtResult TransformStmt(Stmt *S);
+ OwningStmtResult TransformStmt(Stmt *S);
/// \brief Transform the given expression.
///
- /// By default, invokes the derived class's TransformStmt() and downcasts
- /// the result. Subclasses may override this function to provide alternate
- /// behavior.
- Sema::OwningExprResult TransformExpr(Expr *E);
+ /// By default, this routine transforms an expression by delegating to the
+ /// appropriate TransformXXXExpr function to build a new expression.
+ /// Subclasses may override this function to transform expressions using some
+ /// other mechanism.
+ ///
+ /// \returns the transformed expression.
+ OwningExprResult TransformExpr(Expr *E) {
+ return getDerived().TransformExpr(E, /*isAddressOfOperand=*/false);
+ }
+
+ /// \brief Transform the given expression.
+ ///
+ /// By default, this routine transforms an expression by delegating to the
+ /// appropriate TransformXXXExpr function to build a new expression.
+ /// Subclasses may override this function to transform expressions using some
+ /// other mechanism.
+ ///
+ /// \returns the transformed expression.
+ OwningExprResult TransformExpr(Expr *E, bool isAddressOfOperand);
/// \brief Transform the given declaration, which is referenced from a type
/// or expression.
@@ -197,6 +251,17 @@
QualType Transform##CLASS##Type(const CLASS##Type *T);
#include "clang/AST/TypeNodes.def"
+ OwningStmtResult TransformCompoundStmt(Stmt *S, bool IsStmtExpr) {
+ // FIXME: Actually handle this transformation properly.
+ return getDerived().TransformStmt(S);
+ }
+
+#define STMT(Node, Parent)
+#define EXPR(Node, Parent) \
+ OwningExprResult Transform##Node(Node *E);
+#define ABSTRACT_EXPR(Node, Parent)
+#include "clang/AST/StmtNodes.def"
+
/// \brief Build a new pointer type given its pointee type.
///
/// By default, performs semantic analysis when building the pointer type.
@@ -291,7 +356,7 @@
/// Subclasses may override this routine to provide different behavior.
QualType RebuildVariableArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- Sema::ExprArg SizeExpr,
+ ExprArg SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange);
@@ -302,7 +367,7 @@
/// Subclasses may override this routine to provide different behavior.
QualType RebuildDependentSizedArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- Sema::ExprArg SizeExpr,
+ ExprArg SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange);
@@ -327,7 +392,7 @@
/// By default, performs semantic analysis when building the vector type.
/// Subclasses may override this routine to provide different behavior.
QualType RebuildDependentSizedExtVectorType(QualType ElementType,
- Sema::ExprArg SizeExpr,
+ ExprArg SizeExpr,
SourceLocation AttributeLoc);
/// \brief Build a new function type.
@@ -358,7 +423,7 @@
///
/// By default, performs semantic analysis when building the typeof type.
/// Subclasses may override this routine to provide different behavior.
- QualType RebuildTypeOfExprType(Sema::ExprArg Underlying);
+ QualType RebuildTypeOfExprType(ExprArg Underlying);
/// \brief Build a new typeof(type) type.
///
@@ -369,7 +434,7 @@
///
/// By default, performs semantic analysis when building the decltype type.
/// Subclasses may override this routine to provide different behavior.
- QualType RebuildDecltypeType(Sema::ExprArg Underlying);
+ QualType RebuildDecltypeType(ExprArg Underlying);
/// \brief Build a new template specialization type.
///
@@ -473,15 +538,795 @@
/// behavior.
TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
const IdentifierInfo &II);
+
+
+ /// \brief Build a new expression that references a declaration.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildDeclRefExpr(NamedDecl *ND, SourceLocation Loc) {
+ return getSema().BuildDeclarationNameExpr(Loc, ND,
+ /*FIXME:*/false,
+ /*SS=*/0,
+ /*FIXME:*/false);
+ }
+
+ /// \brief Build a new expression in parentheses.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
+ SourceLocation RParen) {
+ return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
+ }
+
+ /// \brief Build a new unary operator expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
+ UnaryOperator::Opcode Opc,
+ ExprArg SubExpr) {
+ return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
+ }
+
+ /// \brief Build a new sizeof or alignof expression with a type argument.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
+ bool isSizeOf, SourceRange R) {
+ return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
+ }
+
+ /// \brief Build a new sizeof or alignof expression with an expression
+ /// argument.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
+ bool isSizeOf, SourceRange R) {
+ OwningExprResult Result
+ = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
+ OpLoc, isSizeOf, R);
+ if (Result.isInvalid())
+ return getSema().ExprError();
+
+ SubExpr.release();
+ return move(Result);
+ }
+
+ /// \brief Build a new array subscript expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
+ SourceLocation LBracketLoc,
+ ExprArg RHS,
+ SourceLocation RBracketLoc) {
+ return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
+ LBracketLoc, move(RHS),
+ RBracketLoc);
+ }
+
+ /// \brief Build a new call expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
+ MultiExprArg Args,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
+ move(Args), CommaLocs, RParenLoc);
+ }
+
+ /// \brief Build a new member access expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
+ bool isArrow, SourceLocation MemberLoc,
+ NamedDecl *Member) {
+ return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
+ isArrow? tok::arrow : tok::period,
+ MemberLoc,
+ /*FIXME*/*Member->getIdentifier(),
+ /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+ }
+
+ /// \brief Build a new binary operator expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
+ BinaryOperator::Opcode Opc,
+ ExprArg LHS, ExprArg RHS) {
+ OwningExprResult Result
+ = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
+ (Expr *)RHS.get());
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ LHS.release();
+ RHS.release();
+ return move(Result);
+ }
+
+ /// \brief Build a new conditional operator expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildConditionalOperator(ExprArg Cond,
+ SourceLocation QuestionLoc,
+ ExprArg LHS,
+ SourceLocation ColonLoc,
+ ExprArg RHS) {
+ return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
+ move(LHS), move(RHS));
+ }
+
+ /// \brief Build a new implicit cast expression.
+ ///
+ /// By default, builds a new implicit cast without any semantic analysis.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
+ ExprArg SubExpr, bool isLvalue) {
+ ImplicitCastExpr *ICE
+ = new (getSema().Context) ImplicitCastExpr(T, Kind,
+ (Expr *)SubExpr.release(),
+ isLvalue);
+ return getSema().Owned(ICE);
+ }
+
+ /// \brief Build a new C-style cast expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
+ QualType ExplicitTy,
+ SourceLocation RParenLoc,
+ ExprArg SubExpr) {
+ return getSema().ActOnCastExpr(/*Scope=*/0,
+ LParenLoc,
+ ExplicitTy.getAsOpaquePtr(),
+ RParenLoc,
+ move(SubExpr));
+ }
+
+ /// \brief Build a new compound literal expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
+ QualType T,
+ SourceLocation RParenLoc,
+ ExprArg Init) {
+ return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
+ RParenLoc, move(Init));
+ }
+
+ /// \brief Build a new extended vector element access expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
+ SourceLocation OpLoc,
+ SourceLocation AccessorLoc,
+ IdentifierInfo &Accessor) {
+ return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
+ tok::period, AccessorLoc,
+ Accessor,
+ /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+ }
+
+ /// \brief Build a new initializer list expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
+ MultiExprArg Inits,
+ SourceLocation RBraceLoc) {
+ return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
+ }
+
+ /// \brief Build a new designated initializer expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
+ MultiExprArg ArrayExprs,
+ SourceLocation EqualOrColonLoc,
+ bool GNUSyntax,
+ ExprArg Init) {
+ OwningExprResult Result
+ = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
+ move(Init));
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ ArrayExprs.release();
+ return move(Result);
+ }
+
+ /// \brief Build a new value-initialized expression.
+ ///
+ /// By default, builds the implicit value initialization without performing
+ /// any semantic analysis. Subclasses may override this routine to provide
+ /// different behavior.
+ OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
+ return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
+ }
+
+ /// \brief Build a new \c va_arg expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
+ QualType T, SourceLocation RParenLoc) {
+ return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
+ RParenLoc);
+ }
+
+ /// \brief Build a new expression list in parentheses.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
+ MultiExprArg SubExprs,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
+ }
+
+ /// \brief Build a new address-of-label expression.
+ ///
+ /// By default, performs semantic analysis, using the name of the label
+ /// rather than attempting to map the label statement itself.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
+ SourceLocation LabelLoc,
+ LabelStmt *Label) {
+ return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
+ }
+
+ /// \brief Build a new GNU statement expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
+ StmtArg SubStmt,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
+ }
+
+ /// \brief Build a new __builtin_types_compatible_p expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+ QualType T1, QualType T2,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
+ T1.getAsOpaquePtr(),
+ T2.getAsOpaquePtr(),
+ RParenLoc);
+ }
+
+ /// \brief Build a new __builtin_choose_expr expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
+ ExprArg Cond, ExprArg LHS, ExprArg RHS,
+ SourceLocation RParenLoc) {
+ return SemaRef.ActOnChooseExpr(BuiltinLoc,
+ move(Cond), move(LHS), move(RHS),
+ RParenLoc);
+ }
+
+ /// \brief Build a new overloaded operator call expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// The semantic analysis provides the behavior of template instantiation,
+ /// copying with transformations that turn what looks like an overloaded
+ /// operator call into a use of a builtin operator, performing
+ /// argument-dependent lookup, etc. Subclasses may override this routine to
+ /// provide different behavior.
+ OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
+ SourceLocation OpLoc,
+ ExprArg Callee,
+ ExprArg First,
+ ExprArg Second);
+
+ /// \brief Build a new C++ "named" cast expression, such as static_cast or
+ /// reinterpret_cast.
+ ///
+ /// By default, this routine dispatches to one of the more-specific routines
+ /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
+ Stmt::StmtClass Class,
+ SourceLocation LAngleLoc,
+ QualType T,
+ SourceLocation RAngleLoc,
+ SourceLocation LParenLoc,
+ ExprArg SubExpr,
+ SourceLocation RParenLoc) {
+ switch (Class) {
+ case Stmt::CXXStaticCastExprClass:
+ return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
+ RAngleLoc, LParenLoc,
+ move(SubExpr), RParenLoc);
+
+ case Stmt::CXXDynamicCastExprClass:
+ return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
+ RAngleLoc, LParenLoc,
+ move(SubExpr), RParenLoc);
+
+ case Stmt::CXXReinterpretCastExprClass:
+ return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
+ RAngleLoc, LParenLoc,
+ move(SubExpr),
+ RParenLoc);
+
+ case Stmt::CXXConstCastExprClass:
+ return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
+ RAngleLoc, LParenLoc,
+ move(SubExpr), RParenLoc);
+
+ default:
+ assert(false && "Invalid C++ named cast");
+ break;
+ }
+
+ return getSema().ExprError();
+ }
+
+ /// \brief Build a new C++ static_cast expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
+ SourceLocation LAngleLoc,
+ QualType T,
+ SourceLocation RAngleLoc,
+ SourceLocation LParenLoc,
+ ExprArg SubExpr,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
+ LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
+ LParenLoc, move(SubExpr), RParenLoc);
+ }
+
+ /// \brief Build a new C++ dynamic_cast expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
+ SourceLocation LAngleLoc,
+ QualType T,
+ SourceLocation RAngleLoc,
+ SourceLocation LParenLoc,
+ ExprArg SubExpr,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
+ LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
+ LParenLoc, move(SubExpr), RParenLoc);
+ }
+
+ /// \brief Build a new C++ reinterpret_cast expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
+ SourceLocation LAngleLoc,
+ QualType T,
+ SourceLocation RAngleLoc,
+ SourceLocation LParenLoc,
+ ExprArg SubExpr,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
+ LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
+ LParenLoc, move(SubExpr), RParenLoc);
+ }
+
+ /// \brief Build a new C++ const_cast expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
+ SourceLocation LAngleLoc,
+ QualType T,
+ SourceLocation RAngleLoc,
+ SourceLocation LParenLoc,
+ ExprArg SubExpr,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
+ LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
+ LParenLoc, move(SubExpr), RParenLoc);
+ }
+
+ /// \brief Build a new C++ functional-style cast expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
+ QualType T,
+ SourceLocation LParenLoc,
+ ExprArg SubExpr,
+ SourceLocation RParenLoc) {
+ Expr *Sub = SubExpr.takeAs<Expr>();
+ return getSema().ActOnCXXTypeConstructExpr(TypeRange,
+ T.getAsOpaquePtr(),
+ LParenLoc,
+ Sema::MultiExprArg(getSema(),
+ (void **)&Sub,
+ 1),
+ /*CommaLocs=*/0,
+ RParenLoc);
+ }
+
+ /// \brief Build a new C++ typeid(type) expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
+ SourceLocation LParenLoc,
+ QualType T,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
+ T.getAsOpaquePtr(), RParenLoc);
+ }
+
+ /// \brief Build a new C++ typeid(expr) expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
+ SourceLocation LParenLoc,
+ ExprArg Operand,
+ SourceLocation RParenLoc) {
+ OwningExprResult Result
+ = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
+ RParenLoc);
+ if (Result.isInvalid())
+ return getSema().ExprError();
+
+ Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
+ return move(Result);
+ }
+
+ /// \brief Build a new C++ "this" expression.
+ ///
+ /// By default, builds a new "this" expression without performing any
+ /// semantic analysis. Subclasses may override this routine to provide
+ /// different behavior.
+ OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
+ QualType ThisType) {
+ return getSema().Owned(
+ new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
+ }
+
+ /// \brief Build a new C++ throw expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
+ return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
+ }
+
+ /// \brief Build a new C++ default-argument expression.
+ ///
+ /// By default, builds a new default-argument expression, which does not
+ /// require any semantic analysis. Subclasses may override this routine to
+ /// provide different behavior.
+ OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
+ return getSema().Owned(new (getSema().Context) CXXDefaultArgExpr(Param));
+ }
+
+ /// \brief Build a new C++ zero-initialization expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
+ SourceLocation LParenLoc,
+ QualType T,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
+ T.getAsOpaquePtr(), LParenLoc,
+ MultiExprArg(getSema(), 0, 0),
+ 0, RParenLoc);
+ }
+
+ /// \brief Build a new C++ conditional declaration expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
+ SourceLocation EqLoc,
+ VarDecl *Var) {
+ return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
+ EqLoc,
+ Var));
+ }
+
+ /// \brief Build a new C++ "new" expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
+ bool UseGlobal,
+ SourceLocation PlacementLParen,
+ MultiExprArg PlacementArgs,
+ SourceLocation PlacementRParen,
+ bool ParenTypeId,
+ QualType AllocType,
+ SourceLocation TypeLoc,
+ SourceRange TypeRange,
+ ExprArg ArraySize,
+ SourceLocation ConstructorLParen,
+ MultiExprArg ConstructorArgs,
+ SourceLocation ConstructorRParen) {
+ return getSema().BuildCXXNew(StartLoc, UseGlobal,
+ PlacementLParen,
+ move(PlacementArgs),
+ PlacementRParen,
+ ParenTypeId,
+ AllocType,
+ TypeLoc,
+ TypeRange,
+ move(ArraySize),
+ ConstructorLParen,
+ move(ConstructorArgs),
+ ConstructorRParen);
+ }
+
+ /// \brief Build a new C++ "delete" expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
+ bool IsGlobalDelete,
+ bool IsArrayForm,
+ ExprArg Operand) {
+ return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
+ move(Operand));
+ }
+
+ /// \brief Build a new unary type trait expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ QualType T,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
+ T.getAsOpaquePtr(), RParenLoc);
+ }
+
+ /// \brief Build a new qualified declaration reference expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildQualifiedDeclRefExpr(NestedNameSpecifier *NNS,
+ SourceRange QualifierRange,
+ NamedDecl *ND,
+ SourceLocation Location,
+ bool IsAddressOfOperand) {
+ CXXScopeSpec SS;
+ SS.setRange(QualifierRange);
+ SS.setScopeRep(NNS);
+ return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
+ Location,
+ ND->getDeclName(),
+ /*Trailing lparen=*/false,
+ &SS,
+ IsAddressOfOperand);
+ }
+
+ /// \brief Build a new (previously unresolved) declaration reference
+ /// expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
+ SourceRange QualifierRange,
+ DeclarationName Name,
+ SourceLocation Location,
+ bool IsAddressOfOperand) {
+ CXXScopeSpec SS;
+ SS.setRange(QualifierRange);
+ SS.setScopeRep(NNS);
+ return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
+ Location,
+ Name,
+ /*Trailing lparen=*/false,
+ &SS,
+ IsAddressOfOperand);
+ }
+
+ /// \brief Build a new template-id expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildTemplateIdExpr(TemplateName Template,
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc) {
+ return getSema().BuildTemplateIdExpr(Template, TemplateLoc,
+ LAngleLoc,
+ TemplateArgs, NumTemplateArgs,
+ RAngleLoc);
+ }
+
+ /// \brief Build a new object-construction expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXConstructExpr(QualType T,
+ CXXConstructorDecl *Constructor,
+ bool IsElidable,
+ MultiExprArg Args) {
+ unsigned NumArgs = Args.size();
+ Expr **ArgsExprs = (Expr **)Args.release();
+ return getSema().Owned(SemaRef.BuildCXXConstructExpr(getSema().Context, T,
+ Constructor,
+ IsElidable,
+ ArgsExprs,
+ NumArgs));
+ }
+
+ /// \brief Build a new object-construction expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
+ QualType T,
+ SourceLocation LParenLoc,
+ MultiExprArg Args,
+ SourceLocation *Commas,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
+ T.getAsOpaquePtr(),
+ LParenLoc,
+ move(Args),
+ Commas,
+ RParenLoc);
+ }
+
+ /// \brief Build a new object-construction expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
+ QualType T,
+ SourceLocation LParenLoc,
+ MultiExprArg Args,
+ SourceLocation *Commas,
+ SourceLocation RParenLoc) {
+ return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
+ /*FIXME*/LParenLoc),
+ T.getAsOpaquePtr(),
+ LParenLoc,
+ move(Args),
+ Commas,
+ RParenLoc);
+ }
+
+ /// \brief Build a new member reference expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg Base,
+ bool IsArrow,
+ SourceLocation OperatorLoc,
+ DeclarationName Name,
+ SourceLocation MemberLoc) {
+ tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
+ CXXScopeSpec SS;
+ Base = SemaRef.ActOnCXXEnterMemberScope(0, SS, move(Base), OpKind);
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ assert(Name.getAsIdentifierInfo() &&
+ "Cannot transform member references with non-identifier members");
+ Base = SemaRef.ActOnMemberReferenceExpr(/*Scope=*/0,
+ move(Base), OperatorLoc, OpKind,
+ MemberLoc,
+ *Name.getAsIdentifierInfo(),
+ /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
+ SemaRef.ActOnCXXExitMemberScope(0, SS);
+ return move(Base);
+ }
+
+ /// \brief Build a new Objective-C @encode expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
+ QualType T,
+ SourceLocation RParenLoc) {
+ return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
+ RParenLoc));
+ }
+
+ /// \brief Build a new Objective-C protocol expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
+ SourceLocation AtLoc,
+ SourceLocation ProtoLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc) {
+ return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
+ Protocol->getIdentifier(),
+ AtLoc,
+ ProtoLoc,
+ LParenLoc,
+ RParenLoc));
+ }
+
+ /// \brief Build a new shuffle vector expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
+ MultiExprArg SubExprs,
+ SourceLocation RParenLoc) {
+ // 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(),
+ BuiltinLoc, false, false);
+ SemaRef.UsualUnaryConversions(Callee);
+
+ // Build the CallExpr
+ unsigned NumSubExprs = SubExprs.size();
+ Expr **Subs = (Expr **)SubExprs.release();
+ CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
+ Subs, NumSubExprs,
+ Builtin->getResultType(),
+ RParenLoc);
+ 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);
+ }
};
+
template<typename Derived>
-Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
- Sema::OwningStmtResult Result = getDerived().TransformStmt(E);
- if (Result.isInvalid())
- return SemaRef.ExprError();
-
- return SemaRef.Owned(cast_or_null<Stmt>(Result.takeAs<Stmt>()));
+Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
+ bool isAddressOfOperand) {
+ if (!E)
+ return SemaRef.Owned(E);
+
+ switch (E->getStmtClass()) {
+ case Stmt::NoStmtClass: break;
+#define STMT(Node, Parent) case Stmt::Node##Class: break;
+#define EXPR(Node, Parent) \
+ case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
+#include "clang/AST/StmtNodes.def"
+ }
+
+ return SemaRef.Owned(E->Retain());
}
template<typename Derived>
@@ -1230,29 +2075,1425 @@
}
//===----------------------------------------------------------------------===//
-// Type reconstruction
+// Expression transformation
//===----------------------------------------------------------------------===//
-
template<typename Derived>
-QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
- return SemaRef.BuildPointerType(PointeeType, 0,
- getDerived().getBaseLocation(),
- getDerived().getBaseEntity());
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
+ return SemaRef.Owned(E->Retain());
}
-
+
template<typename Derived>
-QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
- return SemaRef.BuildBlockPointerType(PointeeType, 0,
- getDerived().getBaseLocation(),
- getDerived().getBaseEntity());
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
+ NamedDecl *ND
+ = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
+ if (!ND)
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() && ND == E->getDecl())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildDeclRefExpr(ND, E->getLocation());
}
-
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
template<typename Derived>
-QualType
-TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
- return SemaRef.BuildReferenceType(ReferentType, true, 0,
- getDerived().getBaseLocation(),
- getDerived().getBaseEntity());
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
+ E->getRParen());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
+ E->getOpcode(),
+ move(SubExpr));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
+ if (E->isArgumentType()) {
+ QualType T = getDerived().TransformType(E->getArgumentType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
+ E->isSizeOf(),
+ E->getSourceRange());
+ }
+
+ Sema::OwningExprResult SubExpr(SemaRef);
+ {
+ // C++0x [expr.sizeof]p1:
+ // The operand is either an expression, which is an unevaluated operand
+ // [...]
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
+ SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
+ return SemaRef.Owned(E->Retain());
+ }
+
+ return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
+ E->isSizeOf(),
+ E->getSourceRange());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
+ OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+
+ if (!getDerived().AlwaysRebuild() &&
+ LHS.get() == E->getLHS() &&
+ RHS.get() == E->getRHS())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildArraySubscriptExpr(move(LHS),
+ /*FIXME:*/E->getLHS()->getLocStart(),
+ move(RHS),
+ E->getRBracketLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
+ // Transform the callee.
+ OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+ if (Callee.isInvalid())
+ return SemaRef.ExprError();
+
+ // Transform arguments.
+ bool ArgChanged = false;
+ ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
+ for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
+ OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ // FIXME: Wrong source location information for the ','.
+ FakeCommaLocs.push_back(
+ SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
+
+ ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
+ Args.push_back(Arg.takeAs<Expr>());
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ Callee.get() == E->getCallee() &&
+ !ArgChanged)
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: Wrong source location information for the '('.
+ SourceLocation FakeLParenLoc
+ = ((Expr *)Callee.get())->getSourceRange().getBegin();
+ return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
+ move_arg(Args),
+ FakeCommaLocs.data(),
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
+ OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ NamedDecl *Member
+ = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
+ if (!Member)
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Base.get() == E->getBase() &&
+ Member == E->getMemberDecl())
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: Bogus source location for the operator
+ SourceLocation FakeOperatorLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
+
+ return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
+ E->isArrow(),
+ E->getMemberLoc(),
+ Member);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
+ assert(false && "Cannot transform abstract class");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
+ OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ LHS.get() == E->getLHS() &&
+ RHS.get() == E->getRHS())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
+ move(LHS), move(RHS));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCompoundAssignOperator(
+ CompoundAssignOperator *E) {
+ return getDerived().TransformBinaryOperator(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
+ OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+ if (Cond.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Cond.get() == E->getCond() &&
+ LHS.get() == E->getLHS() &&
+ RHS.get() == E->getRHS())
+ return SemaRef.Owned(E->Retain());
+
+ // FIXM: ? and : locations are broken.
+ SourceLocation FakeQuestionLoc = E->getCond()->getLocEnd();
+ SourceLocation FakeColonLoc = E->getFalseExpr()->getLocStart();
+ return getDerived().RebuildConditionalOperator(move(Cond),
+ FakeQuestionLoc,
+ move(LHS),
+ FakeColonLoc,
+ move(RHS));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
+ QualType T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType() &&
+ SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
+ move(SubExpr),
+ E->isLvalueCast());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
+ assert(false && "Cannot transform abstract class");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
+ QualType T;
+ {
+ // FIXME: Source location isn't quite accurate.
+ SourceLocation TypeStartLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
+ TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
+
+ T = getDerived().TransformType(E->getTypeAsWritten());
+ if (T.isNull())
+ return SemaRef.ExprError();
+ }
+
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getTypeAsWritten() &&
+ SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
+ E->getRParenLoc(),
+ move(SubExpr));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
+ QualType T;
+ {
+ // FIXME: Source location isn't quite accurate.
+ SourceLocation FakeTypeLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
+ TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
+
+ T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+ }
+
+ OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
+ if (Init.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType() &&
+ Init.get() == E->getInitializer())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
+ /*FIXME:*/E->getInitializer()->getLocEnd(),
+ move(Init));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
+ OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Base.get() == E->getBase())
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: Bad source location
+ SourceLocation FakeOperatorLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
+ return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
+ E->getAccessorLoc(),
+ E->getAccessor());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
+ bool InitChanged = false;
+
+ ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+ for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
+ OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
+ if (Init.isInvalid())
+ return SemaRef.ExprError();
+
+ InitChanged = InitChanged || Init.get() != E->getInit(I);
+ Inits.push_back(Init.takeAs<Expr>());
+ }
+
+ if (!getDerived().AlwaysRebuild() && !InitChanged)
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
+ E->getRBraceLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
+ Designation Desig;
+
+ // Instantiate the initializer value
+ OwningExprResult Init = getDerived().TransformExpr(E->getInit());
+ if (Init.isInvalid())
+ return SemaRef.ExprError();
+
+ // Instantiate the designators.
+ ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
+ bool ExprChanged = false;
+ 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 = getDerived().TransformExpr(E->getArrayIndex(*D));
+ if (Index.isInvalid())
+ return SemaRef.ExprError();
+
+ Desig.AddDesignator(Designator::getArray(Index.get(),
+ D->getLBracketLoc()));
+
+ ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
+ ArrayExprs.push_back(Index.release());
+ continue;
+ }
+
+ assert(D->isArrayRangeDesignator() && "New kind of designator?");
+ OwningExprResult Start
+ = getDerived().TransformExpr(E->getArrayRangeStart(*D));
+ if (Start.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
+ if (End.isInvalid())
+ return SemaRef.ExprError();
+
+ Desig.AddDesignator(Designator::getArrayRange(Start.get(),
+ End.get(),
+ D->getLBracketLoc(),
+ D->getEllipsisLoc()));
+
+ ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
+ End.get() != E->getArrayRangeEnd(*D);
+
+ ArrayExprs.push_back(Start.release());
+ ArrayExprs.push_back(End.release());
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ Init.get() == E->getInit() &&
+ !ExprChanged)
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
+ E->getEqualOrColonLoc(),
+ E->usesGNUSyntax(), move(Init));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformImplicitValueInitExpr(
+ ImplicitValueInitExpr *E) {
+ QualType T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildImplicitValueInitExpr(T);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
+ // FIXME: Do we want the type as written?
+ QualType T;
+
+ {
+ // FIXME: Source location isn't quite accurate.
+ TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
+ T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+ }
+
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType() &&
+ SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
+ T, E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
+ bool ArgumentChanged = false;
+ ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+ for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
+ OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
+ if (Init.isInvalid())
+ return SemaRef.ExprError();
+
+ ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
+ Inits.push_back(Init.takeAs<Expr>());
+ }
+
+ return getDerived().RebuildParenListExpr(E->getLParenLoc(),
+ move_arg(Inits),
+ E->getRParenLoc());
+}
+
+/// \brief Transform an address-of-label expression.
+///
+/// By default, the transformation of an address-of-label expression always
+/// rebuilds the expression, so that the label identifier can be resolved to
+/// the corresponding label statement by semantic analysis.
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
+ return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
+ E->getLabel());
+}
+
+template<typename Derived>
+Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
+ OwningStmtResult SubStmt
+ = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
+ if (SubStmt.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ SubStmt.get() == E->getSubStmt())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildStmtExpr(E->getLParenLoc(),
+ move(SubStmt),
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
+ QualType T1, T2;
+ {
+ // FIXME: Source location isn't quite accurate.
+ TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
+
+ T1 = getDerived().TransformType(E->getArgType1());
+ if (T1.isNull())
+ return SemaRef.ExprError();
+
+ T2 = getDerived().TransformType(E->getArgType2());
+ if (T2.isNull())
+ return SemaRef.ExprError();
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ T1 == E->getArgType1() &&
+ T2 == E->getArgType2())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
+ T1, T2, E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
+ OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+ if (Cond.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Cond.get() == E->getCond() &&
+ LHS.get() == E->getLHS() &&
+ RHS.get() == E->getRHS())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
+ move(Cond), move(LHS), move(RHS),
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+ if (Callee.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
+ if (First.isInvalid())
+ return SemaRef.ExprError();
+
+ OwningExprResult Second(SemaRef);
+ if (E->getNumArgs() == 2) {
+ Second = getDerived().TransformExpr(E->getArg(1));
+ if (Second.isInvalid())
+ return SemaRef.ExprError();
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ Callee.get() == E->getCallee() &&
+ First.get() == E->getArg(0) &&
+ (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
+ E->getOperatorLoc(),
+ move(Callee),
+ move(First),
+ move(Second));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
+ return getDerived().TransformCallExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
+ QualType ExplicitTy;
+ {
+ // FIXME: Source location isn't quite accurate.
+ SourceLocation TypeStartLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
+ TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
+
+ ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
+ if (ExplicitTy.isNull())
+ return SemaRef.ExprError();
+ }
+
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ ExplicitTy == E->getTypeAsWritten() &&
+ SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: Poor source location information here.
+ SourceLocation FakeLAngleLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
+ SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
+ SourceLocation FakeRParenLoc
+ = SemaRef.PP.getLocForEndOfToken(
+ E->getSubExpr()->getSourceRange().getEnd());
+ return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
+ E->getStmtClass(),
+ FakeLAngleLoc,
+ ExplicitTy,
+ FakeRAngleLoc,
+ FakeRAngleLoc,
+ move(SubExpr),
+ FakeRParenLoc);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
+ return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
+ return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
+ CXXReinterpretCastExpr *E) {
+ return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
+ return getDerived().TransformCXXNamedCastExpr(E);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
+ CXXFunctionalCastExpr *E) {
+ QualType ExplicitTy;
+ {
+ TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+
+ ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
+ if (ExplicitTy.isNull())
+ return SemaRef.ExprError();
+ }
+
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ ExplicitTy == E->getTypeAsWritten() &&
+ SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: The end of the type's source range is wrong
+ return getDerived().RebuildCXXFunctionalCastExpr(
+ /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
+ ExplicitTy,
+ /*FIXME:*/E->getSubExpr()->getLocStart(),
+ move(SubExpr),
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
+ if (E->isTypeOperand()) {
+ TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
+
+ QualType T = getDerived().TransformType(E->getTypeOperand());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getTypeOperand())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
+ /*FIXME:*/E->getLocStart(),
+ T,
+ E->getLocEnd());
+ }
+
+ // We don't know whether the expression is potentially evaluated until
+ // after we perform semantic analysis, so the expression is potentially
+ // potentially evaluated.
+ EnterExpressionEvaluationContext Unevaluated(SemaRef,
+ Action::PotentiallyPotentiallyEvaluated);
+
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ SubExpr.get() == E->getExprOperand())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
+ /*FIXME:*/E->getLocStart(),
+ move(SubExpr),
+ E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
+ CXXNullPtrLiteralExpr *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
+ TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
+
+ QualType T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ SubExpr.get() == E->getSubExpr())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+ ParmVarDecl *Param
+ = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
+ if (!Param)
+ return SemaRef.ExprError();
+
+ if (getDerived().AlwaysRebuild() &&
+ Param == E->getParam())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXDefaultArgExpr(Param);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+ TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+
+ QualType T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
+ /*FIXME:*/E->getTypeBeginLoc(),
+ T,
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
+ VarDecl *Var
+ = cast_or_null<VarDecl>(getDerived().TransformDecl(E->getVarDecl()));
+ if (!Var)
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Var == E->getVarDecl())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
+ /*FIXME:*/E->getStartLoc(),
+ Var);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
+ // Transform the type that we're allocating
+ TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
+ QualType AllocType = getDerived().TransformType(E->getAllocatedType());
+ if (AllocType.isNull())
+ return SemaRef.ExprError();
+
+ // Transform the size of the array we're allocating (if any).
+ OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
+ if (ArraySize.isInvalid())
+ return SemaRef.ExprError();
+
+ // Transform the placement arguments (if any).
+ bool ArgumentChanged = false;
+ ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
+ for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
+ OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
+ 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 = getDerived().TransformExpr(E->getConstructorArg(I));
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
+ ConstructorArgs.push_back(Arg.take());
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ AllocType == E->getAllocatedType() &&
+ ArraySize.get() == E->getArraySize() &&
+ !ArgumentChanged)
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXNewExpr(E->getLocStart(),
+ E->isGlobalNew(),
+ /*FIXME:*/E->getLocStart(),
+ move_arg(PlacementArgs),
+ /*FIXME:*/E->getLocStart(),
+ E->isParenTypeId(),
+ AllocType,
+ /*FIXME:*/E->getLocStart(),
+ /*FIXME:*/SourceRange(),
+ move(ArraySize),
+ /*FIXME:*/E->getLocStart(),
+ move_arg(ConstructorArgs),
+ E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
+ OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
+ if (Operand.isInvalid())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Operand.get() == E->getArgument())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
+ E->isGlobalDelete(),
+ E->isArrayForm(),
+ move(Operand));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
+ UnresolvedFunctionNameExpr *E) {
+ // There is no transformation we can apply to an unresolved function name.
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+ TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
+
+ QualType T = getDerived().TransformType(E->getQueriedType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getQueriedType())
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: Bad location information
+ SourceLocation FakeLParenLoc
+ = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
+
+ return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
+ E->getLocStart(),
+ /*FIXME:*/FakeLParenLoc,
+ T,
+ E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformQualifiedDeclRefExpr(QualifiedDeclRefExpr *E) {
+ NestedNameSpecifier *NNS
+ = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
+ if (!NNS)
+ return SemaRef.ExprError();
+
+ NamedDecl *ND
+ = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
+ if (!ND)
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ NNS == E->getQualifier() &&
+ ND == E->getDecl())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildQualifiedDeclRefExpr(NNS,
+ E->getQualifierRange(),
+ ND,
+ E->getLocation(),
+ /*FIXME:*/false);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
+ UnresolvedDeclRefExpr *E) {
+ NestedNameSpecifier *NNS
+ = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
+ E->getQualifierRange());
+ if (!NNS)
+ return SemaRef.ExprError();
+
+ // FIXME: Transform the declaration name
+ DeclarationName Name = E->getDeclName();
+
+ if (!getDerived().AlwaysRebuild() &&
+ NNS == E->getQualifier() &&
+ Name == E->getDeclName())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
+ E->getQualifierRange(),
+ Name,
+ E->getLocation(),
+ /*FIXME:*/false);
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
+ TemplateName Template
+ = getDerived().TransformTemplateName(E->getTemplateName());
+ if (Template.isNull())
+ return SemaRef.ExprError();
+
+ llvm::SmallVector<TemplateArgument, 4> TransArgs;
+ for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+ TemplateArgument TransArg
+ = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
+ if (TransArg.isNull())
+ return SemaRef.ExprError();
+
+ TransArgs.push_back(TransArg);
+ }
+
+ // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
+ // compare template arguments (yet).
+
+ // FIXME: It's possible that we'll find out now that the template name
+ // actually refers to a type, in which case the caller is actually dealing
+ // with a functional cast. Give a reasonable error message!
+ return getDerived().RebuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
+ E->getLAngleLoc(),
+ TransArgs.data(),
+ TransArgs.size(),
+ E->getRAngleLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
+ TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
+
+ QualType T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ CXXConstructorDecl *Constructor
+ = cast_or_null<CXXConstructorDecl>(
+ getDerived().TransformDecl(E->getConstructor()));
+ if (!Constructor)
+ return SemaRef.ExprError();
+
+ bool ArgumentChanged = false;
+ ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
+ ArgEnd = E->arg_end();
+ Arg != ArgEnd; ++Arg) {
+ OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+ if (TransArg.isInvalid())
+ return SemaRef.ExprError();
+
+ ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
+ Args.push_back(TransArg.takeAs<Expr>());
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType() &&
+ Constructor == E->getConstructor() &&
+ !ArgumentChanged)
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
+ move_arg(Args));
+}
+
+/// \brief Transform a C++ temporary-binding expression.
+///
+/// The transformation of a temporary-binding expression always attempts to
+/// bind a new temporary variable to its subexpression, even if the
+/// subexpression itself did not change, because the temporary variable itself
+/// must be unique.
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
+}
+
+/// \brief Transform a C++ expression that contains temporaries that should
+/// be destroyed after the expression is evaluated.
+///
+/// The transformation of a full expression always attempts to build a new
+/// CXXExprWithTemporaries expression, even if the
+/// subexpression itself did not change, because it will need to capture the
+/// the new temporary variables introduced in the subexpression.
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXExprWithTemporaries(
+ CXXExprWithTemporaries *E) {
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ return SemaRef.Owned(
+ SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
+ E->shouldDestroyTemporaries()));
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
+ CXXTemporaryObjectExpr *E) {
+ TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+ QualType T = getDerived().TransformType(E->getType());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ CXXConstructorDecl *Constructor
+ = cast_or_null<CXXConstructorDecl>(
+ getDerived().TransformDecl(E->getConstructor()));
+ if (!Constructor)
+ return SemaRef.ExprError();
+
+ bool ArgumentChanged = false;
+ 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 TransArg = getDerived().TransformExpr(*Arg);
+ if (TransArg.isInvalid())
+ return SemaRef.ExprError();
+
+ ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
+ Args.push_back((Expr *)TransArg.release());
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getType() &&
+ Constructor == E->getConstructor() &&
+ !ArgumentChanged)
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: Bogus location information
+ SourceLocation CommaLoc;
+ if (Args.size() > 1) {
+ Expr *First = (Expr *)Args[0];
+ CommaLoc
+ = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
+ }
+ return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
+ T,
+ /*FIXME:*/E->getTypeBeginLoc(),
+ move_arg(Args),
+ &CommaLoc,
+ E->getLocEnd());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
+ CXXUnresolvedConstructExpr *E) {
+ TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
+ QualType T = getDerived().TransformType(E->getTypeAsWritten());
+ if (T.isNull())
+ return SemaRef.ExprError();
+
+ bool ArgumentChanged = false;
+ 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 TransArg = getDerived().TransformExpr(*Arg);
+ if (TransArg.isInvalid())
+ return SemaRef.ExprError();
+
+ ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
+ FakeCommaLocs.push_back(
+ SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
+ Args.push_back(TransArg.takeAs<Expr>());
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ T == E->getTypeAsWritten() &&
+ !ArgumentChanged)
+ return SemaRef.Owned(E->Retain());
+
+ // FIXME: we're faking the locations of the commas
+ return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
+ T,
+ E->getLParenLoc(),
+ move_arg(Args),
+ FakeCommaLocs.data(),
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
+ CXXUnresolvedMemberExpr *E) {
+ // Transform the base of the expression.
+ OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+ if (Base.isInvalid())
+ return SemaRef.ExprError();
+
+ // FIXME: Transform the declaration name
+ DeclarationName Name = E->getMember();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Base.get() == E->getBase() &&
+ Name == E->getMember())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
+ E->isArrow(),
+ E->getOperatorLoc(),
+ E->getMember(),
+ E->getMemberLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
+ // FIXME: poor source location
+ TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
+ QualType EncodedType = getDerived().TransformType(E->getEncodedType());
+ if (EncodedType.isNull())
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ EncodedType == E->getEncodedType())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
+ EncodedType,
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform Objective-C expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
+ ObjCProtocolDecl *Protocol
+ = cast_or_null<ObjCProtocolDecl>(
+ getDerived().TransformDecl(E->getProtocol()));
+ if (!Protocol)
+ return SemaRef.ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ Protocol == E->getProtocol())
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildObjCProtocolExpr(Protocol,
+ E->getAtLoc(),
+ /*FIXME:*/E->getAtLoc(),
+ /*FIXME:*/E->getAtLoc(),
+ E->getRParenLoc());
+
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform Objective-C expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform Objective-C expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCKVCRefExpr(ObjCKVCRefExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform Objective-C expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform Objective-C expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform Objective-C expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
+ bool ArgumentChanged = false;
+ ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
+ for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
+ OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
+ if (SubExpr.isInvalid())
+ return SemaRef.ExprError();
+
+ ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
+ SubExprs.push_back(SubExpr.takeAs<Expr>());
+ }
+
+ if (!getDerived().AlwaysRebuild() &&
+ !ArgumentChanged)
+ return SemaRef.Owned(E->Retain());
+
+ return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
+ move_arg(SubExprs),
+ E->getRParenLoc());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform block expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
+ // FIXME: Implement this!
+ assert(false && "Cannot transform block-related expressions yet");
+ return SemaRef.Owned(E->Retain());
+}
+
+//===----------------------------------------------------------------------===//
+// Type reconstruction
+//===----------------------------------------------------------------------===//
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
+ return SemaRef.BuildPointerType(PointeeType, 0,
+ getDerived().getBaseLocation(),
+ getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
+ return SemaRef.BuildBlockPointerType(PointeeType, 0,
+ getDerived().getBaseLocation(),
+ getDerived().getBaseEntity());
+}
+
+template<typename Derived>
+QualType
+TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
+ return SemaRef.BuildReferenceType(ReferentType, true, 0,
+ getDerived().getBaseLocation(),
+ getDerived().getBaseEntity());
}
template<typename Derived>
@@ -1352,7 +3593,7 @@
QualType
TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- Sema::ExprArg SizeExpr,
+ ExprArg SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange) {
return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
@@ -1364,7 +3605,7 @@
QualType
TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
ArrayType::ArraySizeModifier SizeMod,
- Sema::ExprArg SizeExpr,
+ ExprArg SizeExpr,
unsigned IndexTypeQuals,
SourceRange BracketsRange) {
return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
@@ -1395,7 +3636,7 @@
template<typename Derived>
QualType
TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
- Sema::ExprArg SizeExpr,
+ ExprArg SizeExpr,
SourceLocation AttributeLoc) {
return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
}
@@ -1413,7 +3654,7 @@
}
template<typename Derived>
-QualType TreeTransform<Derived>::RebuildTypeOfExprType(Sema::ExprArg E) {
+QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
}
@@ -1423,7 +3664,7 @@
}
template<typename Derived>
-QualType TreeTransform<Derived>::RebuildDecltypeType(Sema::ExprArg E) {
+QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
}
@@ -1521,6 +3762,87 @@
return Template.getAsVal<TemplateName>();
}
+
+template<typename Derived>
+Sema::OwningExprResult
+TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
+ SourceLocation OpLoc,
+ ExprArg Callee,
+ ExprArg First,
+ ExprArg Second) {
+ Expr *FirstExpr = (Expr *)First.get();
+ Expr *SecondExpr = (Expr *)Second.get();
+ bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
+
+ // Determine whether this should be a builtin operation.
+ if (SecondExpr == 0 || isPostIncDec) {
+ if (!FirstExpr->getType()->isOverloadableType()) {
+ // The argument is not of overloadable type, so try to create a
+ // built-in unary operation.
+ UnaryOperator::Opcode Opc
+ = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
+
+ return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
+ }
+ } else {
+ if (!FirstExpr->getType()->isOverloadableType() &&
+ !SecondExpr->getType()->isOverloadableType()) {
+ // Neither of the arguments is an overloadable type, so try to
+ // create a built-in binary operation.
+ BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
+ OwningExprResult Result
+ = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ First.release();
+ Second.release();
+ return move(Result);
+ }
+ }
+
+ // Compute the transformed set of functions (and function templates) to be
+ // used during overload resolution.
+ Sema::FunctionSet Functions;
+
+ DeclRefExpr *DRE = cast<DeclRefExpr>((Expr *)Callee.get());
+ 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.
+ Expr *Args[2] = { FirstExpr, SecondExpr };
+ unsigned NumArgs = 1 + (SecondExpr != 0);
+ DeclarationName OpName
+ = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
+ SemaRef.ArgumentDependentLookup(OpName, Args, NumArgs, Functions);
+
+ // Create the overloaded operator invocation for unary operators.
+ if (NumArgs == 1 || isPostIncDec) {
+ UnaryOperator::Opcode Opc
+ = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
+ return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
+ }
+
+ // Create the overloaded operator invocation for binary operators.
+ BinaryOperator::Opcode Opc =
+ BinaryOperator::getOverloadedOpcode(Op);
+ OwningExprResult Result
+ = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
+ if (Result.isInvalid())
+ return SemaRef.ExprError();
+
+ First.release();
+ Second.release();
+ return move(Result);
+}
} // end namespace clang
More information about the cfe-commits
mailing list