Convert a bunch of actions to smart pointers, and also bring PrintParserCallbacks a bit more in line with reality.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67029 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e5a2520..5450d19 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -56,76 +56,81 @@
}
/// ActOnCXXTypeidOfType - Parse typeid( type-id ).
-Action::ExprResult
+Action::OwningExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
NamespaceDecl *StdNs = GetStdNamespace();
if (!StdNs)
- return Diag(OpLoc, diag::err_need_header_before_typeid);
+ return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
Decl *TypeInfoDecl = LookupQualifiedName(StdNs, TypeInfoII, LookupTagName);
RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
if (!TypeInfoRecordDecl)
- return Diag(OpLoc, diag::err_need_header_before_typeid);
+ return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl);
- return new (Context) CXXTypeidExpr(isType, TyOrExpr, TypeInfoType.withConst(),
- SourceRange(OpLoc, RParenLoc));
+ return Owned(new (Context) CXXTypeidExpr(isType, TyOrExpr,
+ TypeInfoType.withConst(),
+ SourceRange(OpLoc, RParenLoc)));
}
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
-Action::ExprResult
+Action::OwningExprResult
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
"Unknown C++ Boolean value!");
- return new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
+ return Owned(new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true,
+ Context.BoolTy, OpLoc));
}
/// ActOnCXXThrow - Parse throw expressions.
-Action::ExprResult
-Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprTy *E) {
- return new (Context) CXXThrowExpr((Expr*)E, Context.VoidTy, OpLoc);
+Action::OwningExprResult
+Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprArg E) {
+ return Owned(new (Context) CXXThrowExpr((Expr*)E.release(), Context.VoidTy,
+ OpLoc));
}
-Action::ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
+Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
/// C++ 9.3.2: In the body of a non-static member function, the keyword this
/// is a non-lvalue expression whose value is the address of the object for
/// which the function is called.
- if (!isa<FunctionDecl>(CurContext)) {
- Diag(ThisLoc, diag::err_invalid_this_use);
- return ExprResult(true);
- }
+ if (!isa<FunctionDecl>(CurContext))
+ return ExprError(Diag(ThisLoc, diag::err_invalid_this_use));
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext))
if (MD->isInstance())
- return new (Context) CXXThisExpr(ThisLoc, MD->getThisType(Context));
+ return Owned(new (Context) CXXThisExpr(ThisLoc,
+ MD->getThisType(Context)));
- return Diag(ThisLoc, diag::err_invalid_this_use);
+ return ExprError(Diag(ThisLoc, diag::err_invalid_this_use));
}
/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
/// Can be interpreted either as function-style casting ("int(x)")
/// or class type construction ("ClassType(x,y,z)")
/// or creation of a value-initialized type ("int()").
-Action::ExprResult
+Action::OwningExprResult
Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
SourceLocation LParenLoc,
- ExprTy **ExprTys, unsigned NumExprs,
+ MultiExprArg exprs,
SourceLocation *CommaLocs,
SourceLocation RParenLoc) {
assert(TypeRep && "Missing type!");
QualType Ty = QualType::getFromOpaquePtr(TypeRep);
- Expr **Exprs = (Expr**)ExprTys;
+ unsigned NumExprs = exprs.size();
+ Expr **Exprs = (Expr**)exprs.get();
SourceLocation TyBeginLoc = TypeRange.getBegin();
SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
- if (Ty->isDependentType() ||
+ if (Ty->isDependentType() ||
CallExpr::hasAnyTypeDependentArguments(Exprs, NumExprs)) {
- return new (Context) CXXTemporaryObjectExpr(0, Ty, TyBeginLoc,
- Exprs, NumExprs, RParenLoc);
+ exprs.release();
+ return Owned(new (Context) CXXTemporaryObjectExpr(0, Ty, TyBeginLoc,
+ Exprs, NumExprs,
+ RParenLoc));
}
@@ -136,14 +141,16 @@
//
if (NumExprs == 1) {
if (CheckCastTypes(TypeRange, Ty, Exprs[0]))
- return true;
- return new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(), Ty,
- TyBeginLoc, Exprs[0], RParenLoc);
+ return ExprError();
+ exprs.release();
+ return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
+ Ty, TyBeginLoc, Exprs[0],
+ RParenLoc));
}
if (const RecordType *RT = Ty->getAsRecordType()) {
CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
-
+
if (NumExprs > 1 || Record->hasUserDeclaredConstructor()) {
CXXConstructorDecl *Constructor
= PerformInitializationByConstructor(Ty, Exprs, NumExprs,
@@ -152,12 +159,14 @@
RParenLoc),
DeclarationName(),
IK_Direct);
-
- if (!Constructor)
- return true;
- return new (Context) CXXTemporaryObjectExpr(Constructor, Ty, TyBeginLoc,
- Exprs, NumExprs, RParenLoc);
+ if (!Constructor)
+ return ExprError();
+
+ exprs.release();
+ return Owned(new (Context) CXXTemporaryObjectExpr(Constructor, Ty,
+ TyBeginLoc, Exprs,
+ NumExprs, RParenLoc));
}
// Fall through to value-initialize an object of class type that
@@ -169,8 +178,9 @@
// be a class with a suitably declared constructor.
//
if (NumExprs > 1)
- return Diag(CommaLocs[0], diag::err_builtin_func_cast_more_than_one_arg)
- << FullRange;
+ return ExprError(Diag(CommaLocs[0],
+ diag::err_builtin_func_cast_more_than_one_arg)
+ << FullRange);
assert(NumExprs == 0 && "Expected 0 expressions");
@@ -180,13 +190,15 @@
// rvalue of the specified type, which is value-initialized.
//
if (Ty->isArrayType())
- return Diag(TyBeginLoc, diag::err_value_init_for_array_type) << FullRange;
+ return ExprError(Diag(TyBeginLoc,
+ diag::err_value_init_for_array_type) << FullRange);
if (!Ty->isDependentType() && !Ty->isVoidType() &&
- RequireCompleteType(TyBeginLoc, Ty,
- diag::err_invalid_incomplete_type_use, FullRange))
- return true;
+ RequireCompleteType(TyBeginLoc, Ty,
+ diag::err_invalid_incomplete_type_use, FullRange))
+ return ExprError();
- return new (Context) CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc);
+ exprs.release();
+ return Owned(new (Context) CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc));
}
@@ -195,13 +207,12 @@
/// or
/// @code ::new Foo(23, "hello") @endcode
/// For the interpretation of this heap of arguments, consult the base version.
-Action::ExprResult
+Action::OwningExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
- SourceLocation PlacementLParen,
- ExprTy **PlacementArgs, unsigned NumPlaceArgs,
+ SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
SourceLocation PlacementRParen, bool ParenTypeId,
Declarator &D, SourceLocation ConstructorLParen,
- ExprTy **ConstructorArgs, unsigned NumConsArgs,
+ MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen)
{
Expr *ArraySize = 0;
@@ -211,21 +222,21 @@
D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
DeclaratorChunk &Chunk = D.getTypeObject(0);
if (Chunk.Arr.hasStatic)
- return Diag(Chunk.Loc, diag::err_static_illegal_in_new)
- << D.getSourceRange();
+ return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
+ << D.getSourceRange());
if (!Chunk.Arr.NumElts)
- return Diag(Chunk.Loc, diag::err_array_new_needs_size)
- << D.getSourceRange();
+ return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
+ << D.getSourceRange());
ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts);
Skip = 1;
}
QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, Skip);
if (D.getInvalidType())
- return true;
+ return ExprError();
if (CheckAllocatedType(AllocType, D))
- return true;
+ return ExprError();
QualType ResultType = AllocType->isDependentType()
? Context.DependentTy
@@ -239,9 +250,9 @@
if (ArraySize && !ArraySize->isTypeDependent()) {
QualType SizeType = ArraySize->getType();
if (!SizeType->isIntegralType() && !SizeType->isEnumeralType())
- return Diag(ArraySize->getSourceRange().getBegin(),
- diag::err_array_size_not_integral)
- << SizeType << ArraySize->getSourceRange();
+ return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
+ diag::err_array_size_not_integral)
+ << SizeType << ArraySize->getSourceRange());
// Let's see if this is a constant < 0. If so, we reject it out of hand.
// We don't care about special rules, so we tell the machinery it's not
// evaluated - it gives us a result in more cases.
@@ -250,23 +261,24 @@
if (ArraySize->isIntegerConstantExpr(Value, Context, 0, false)) {
if (Value < llvm::APSInt(
llvm::APInt::getNullValue(Value.getBitWidth()), false))
- return Diag(ArraySize->getSourceRange().getBegin(),
- diag::err_typecheck_negative_array_size)
- << ArraySize->getSourceRange();
+ return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
+ diag::err_typecheck_negative_array_size)
+ << ArraySize->getSourceRange());
}
}
}
FunctionDecl *OperatorNew = 0;
FunctionDecl *OperatorDelete = 0;
- Expr **PlaceArgs = (Expr**)PlacementArgs;
+ Expr **PlaceArgs = (Expr**)PlacementArgs.get();
+ unsigned NumPlaceArgs = PlacementArgs.size();
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(PlaceArgs, NumPlaceArgs) &&
FindAllocationFunctions(StartLoc,
SourceRange(PlacementLParen, PlacementRParen),
UseGlobal, AllocType, ArraySize, PlaceArgs,
NumPlaceArgs, OperatorNew, OperatorDelete))
- return true;
+ return ExprError();
bool Init = ConstructorLParen.isValid();
// --- Choosing a constructor ---
@@ -287,7 +299,8 @@
// to C++0x rules.
// 2) Otherwise, the object is direct-initialized.
CXXConstructorDecl *Constructor = 0;
- Expr **ConsArgs = (Expr**)ConstructorArgs;
+ Expr **ConsArgs = (Expr**)ConstructorArgs.get();
+ unsigned NumConsArgs = ConstructorArgs.size();
if (AllocType->isDependentType()) {
// Skip all the checks.
}
@@ -303,15 +316,13 @@
RT->getDecl()->getDeclName(),
NumConsArgs != 0 ? IK_Direct : IK_Default);
if (!Constructor)
- return true;
+ return ExprError();
} else {
if (!Init) {
// FIXME: Check that no subpart is const.
- if (AllocType.isConstQualified()) {
- Diag(StartLoc, diag::err_new_uninitialized_const)
- << D.getSourceRange();
- return true;
- }
+ if (AllocType.isConstQualified())
+ return ExprError(Diag(StartLoc, diag::err_new_uninitialized_const)
+ << D.getSourceRange());
} else if (NumConsArgs == 0) {
// Object is value-initialized. Do nothing.
} else if (NumConsArgs == 1) {
@@ -320,19 +331,22 @@
if (CheckInitializerTypes(ConsArgs[0], AllocType, StartLoc,
DeclarationName() /*AllocType.getAsString()*/,
/*DirectInit=*/true))
- return true;
+ return ExprError();
} else {
- Diag(StartLoc, diag::err_builtin_direct_init_more_than_one_arg)
- << SourceRange(ConstructorLParen, ConstructorRParen);
+ return ExprError(Diag(StartLoc,
+ diag::err_builtin_direct_init_more_than_one_arg)
+ << SourceRange(ConstructorLParen, ConstructorRParen));
}
}
// FIXME: Also check that the destructor is accessible. (C++ 5.3.4p16)
- return new (Context) CXXNewExpr(UseGlobal, OperatorNew, PlaceArgs,
+ PlacementArgs.release();
+ ConstructorArgs.release();
+ return Owned(new (Context) CXXNewExpr(UseGlobal, OperatorNew, PlaceArgs,
NumPlaceArgs, ParenTypeId, ArraySize, Constructor, Init,
ConsArgs, NumConsArgs, OperatorDelete, ResultType,
- StartLoc, Init ? ConstructorRParen : SourceLocation());
+ StartLoc, Init ? ConstructorRParen : SourceLocation()));
}
/// CheckAllocatedType - Checks that a type is suitable as the allocated type
@@ -576,16 +590,16 @@
/// @code ::delete ptr; @endcode
/// or
/// @code delete [] ptr; @endcode
-Action::ExprResult
+Action::OwningExprResult
Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
- bool ArrayForm, ExprTy *Operand)
+ bool ArrayForm, ExprArg Operand)
{
// C++ 5.3.5p1: "The operand shall have a pointer type, or a class type
// having a single conversion function to a pointer type. The result has
// type void."
// DR599 amends "pointer type" to "pointer to object type" in both cases.
- Expr *Ex = (Expr *)Operand;
+ Expr *Ex = (Expr *)Operand.get();
if (!Ex->isTypeDependent()) {
QualType Type = Ex->getType();
@@ -593,41 +607,39 @@
// FIXME: Find that one conversion function and amend the type.
}
- if (!Type->isPointerType()) {
- Diag(StartLoc, diag::err_delete_operand) << Type << Ex->getSourceRange();
- return true;
- }
+ if (!Type->isPointerType())
+ return ExprError(Diag(StartLoc, diag::err_delete_operand)
+ << Type << Ex->getSourceRange());
QualType Pointee = Type->getAsPointerType()->getPointeeType();
- if (!Pointee->isVoidType() &&
+ if (!Pointee->isVoidType() &&
RequireCompleteType(StartLoc, Pointee, diag::warn_delete_incomplete,
Ex->getSourceRange()))
- return true;
- else if (!Pointee->isObjectType()) {
- Diag(StartLoc, diag::err_delete_operand)
- << Type << Ex->getSourceRange();
- return true;
- }
+ return ExprError();
+ else if (!Pointee->isObjectType())
+ return ExprError(Diag(StartLoc, diag::err_delete_operand)
+ << Type << Ex->getSourceRange());
// FIXME: Look up the correct operator delete overload and pass a pointer
// along.
// FIXME: Check access and ambiguity of operator delete and destructor.
}
- return new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm, 0,
- Ex, StartLoc);
+ Operand.release();
+ return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
+ 0, Ex, StartLoc));
}
/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
/// C++ if/switch/while/for statement.
/// e.g: "if (int x = f()) {...}"
-Action::ExprResult
+Action::OwningExprResult
Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc,
Declarator &D,
SourceLocation EqualLoc,
- ExprTy *AssignExprVal) {
- assert(AssignExprVal && "Null assignment expression");
+ ExprArg AssignExprVal) {
+ assert(AssignExprVal.get() && "Null assignment expression");
// C++ 6.4p2:
// The declarator shall not specify a function or an array.
@@ -642,8 +654,8 @@
if (Ty->isFunctionType()) { // The declarator shall not specify a function...
// We exit without creating a CXXConditionDeclExpr because a FunctionDecl
// would be created and CXXConditionDeclExpr wants a VarDecl.
- return Diag(StartLoc, diag::err_invalid_use_of_function_type)
- << SourceRange(StartLoc, EqualLoc);
+ return ExprError(Diag(StartLoc, diag::err_invalid_use_of_function_type)
+ << SourceRange(StartLoc, EqualLoc));
} else if (Ty->isArrayType()) { // ...or an array.
Diag(StartLoc, diag::err_invalid_use_of_array_type)
<< SourceRange(StartLoc, EqualLoc);
@@ -661,15 +673,15 @@
DeclTy *Dcl = ActOnDeclarator(S, D, 0);
if (!Dcl)
- return true;
- AddInitializerToDecl(Dcl, ExprArg(*this, AssignExprVal));
+ return ExprError();
+ AddInitializerToDecl(Dcl, move(AssignExprVal));
// Mark this variable as one that is declared within a conditional.
if (VarDecl *VD = dyn_cast<VarDecl>((Decl *)Dcl))
VD->setDeclaredInCondition(true);
- return new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc,
- cast<VarDecl>(static_cast<Decl *>(Dcl)));
+ return Owned(new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc,
+ cast<VarDecl>(static_cast<Decl *>(Dcl))));
}
/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.