summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp604
1 files changed, 307 insertions, 297 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 090400fc4e23..5720d931b66b 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -11,28 +11,31 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
#include "llvm/ADT/STLExtras.h"
using namespace clang;
-
-Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
- IdentifierInfo &II,
- SourceLocation NameLoc,
- Scope *S, CXXScopeSpec &SS,
- TypeTy *ObjectTypePtr,
- bool EnteringContext) {
+using namespace sema;
+
+ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
+ IdentifierInfo &II,
+ SourceLocation NameLoc,
+ Scope *S, CXXScopeSpec &SS,
+ ParsedType ObjectTypePtr,
+ bool EnteringContext) {
// Determine where to perform name lookup.
// FIXME: This area of the standard is very messy, and the current
@@ -149,7 +152,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
// FIXME: Should we be suppressing ambiguities here?
if (Found.isAmbiguous())
- return 0;
+ return ParsedType();
if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
QualType T = Context.getTypeDeclType(Type);
@@ -158,7 +161,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
Context.hasSameUnqualifiedType(T, SearchType)) {
// We found our type!
- return T.getAsOpaquePtr();
+ return ParsedType::make(T);
}
}
@@ -191,7 +194,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
= dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
Template->getCanonicalDecl())
- return MemberOfType.getAsOpaquePtr();
+ return ParsedType::make(MemberOfType);
}
continue;
@@ -210,7 +213,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
// specialized.
if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
- return MemberOfType.getAsOpaquePtr();
+ return ParsedType::make(MemberOfType);
continue;
}
@@ -221,7 +224,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
= SpecName.getAsDependentTemplateName()) {
if (DepTemplate->isIdentifier() &&
DepTemplate->getIdentifier() == Template->getIdentifier())
- return MemberOfType.getAsOpaquePtr();
+ return ParsedType::make(MemberOfType);
continue;
}
@@ -242,8 +245,10 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
Range = SourceRange(NameLoc);
}
- return CheckTypenameType(ETK_None, NNS, II, SourceLocation(),
- Range, NameLoc).getAsOpaquePtr();
+ QualType T = CheckTypenameType(ETK_None, NNS, II,
+ SourceLocation(),
+ Range, NameLoc);
+ return ParsedType::make(T);
}
if (ObjectTypePtr)
@@ -252,11 +257,11 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
else
Diag(NameLoc, diag::err_destructor_class_name);
- return 0;
+ return ParsedType();
}
/// \brief Build a C++ typeid expression with a type operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
SourceLocation TypeidLoc,
TypeSourceInfo *Operand,
SourceLocation RParenLoc) {
@@ -279,12 +284,11 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
}
/// \brief Build a C++ typeid expression with an expression operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
SourceLocation TypeidLoc,
- ExprArg Operand,
+ Expr *E,
SourceLocation RParenLoc) {
bool isUnevaluatedOperand = true;
- Expr *E = static_cast<Expr *>(Operand.get());
if (E && !E->isTypeDependent()) {
QualType T = E->getType();
if (const RecordType *RecordT = T->getAs<RecordType>()) {
@@ -296,10 +300,10 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
return ExprError();
// C++ [expr.typeid]p3:
- // When typeid is applied to an expression other than an lvalue of a
+ // When typeid is applied to an expression other than an glvalue of a
// polymorphic class type [...] [the] expression is an unevaluated
// operand. [...]
- if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid) {
+ if (RecordD->isPolymorphic() && E->Classify(Context).isGLValue()) {
isUnevaluatedOperand = false;
// We require a vtable to query the type at run time.
@@ -316,9 +320,7 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
if (!Context.hasSameType(T, UnqualT)) {
T = UnqualT;
- ImpCastExprToType(E, UnqualT, CastExpr::CK_NoOp, E->isLvalue(Context));
- Operand.release();
- Operand = Owned(E);
+ ImpCastExprToType(E, UnqualT, CK_NoOp, CastCategory(E));
}
}
@@ -329,12 +331,12 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
ExprEvalContexts.back().Context = Unevaluated;
return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
- Operand.takeAs<Expr>(),
+ E,
SourceRange(TypeidLoc, RParenLoc)));
}
/// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
// Find the std::type_info type.
@@ -343,7 +345,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
- LookupQualifiedName(R, StdNamespace);
+ LookupQualifiedName(R, getStdNamespace());
RecordDecl *TypeInfoRecordDecl = R.getAsSingle<RecordDecl>();
if (!TypeInfoRecordDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
@@ -353,7 +355,8 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
if (isType) {
// The operand is a type; handle it as such.
TypeSourceInfo *TInfo = 0;
- QualType T = GetTypeFromParser(TyOrExpr, &TInfo);
+ QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
+ &TInfo);
if (T.isNull())
return ExprError();
@@ -364,11 +367,11 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
}
// The operand is an expression.
- return BuildCXXTypeId(TypeInfoType, OpLoc, Owned((Expr*)TyOrExpr), RParenLoc);
+ return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
}
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
"Unknown C++ Boolean value!");
@@ -377,15 +380,14 @@ Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
}
/// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
}
/// ActOnCXXThrow - Parse throw expressions.
-Action::OwningExprResult
-Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprArg E) {
- Expr *Ex = E.takeAs<Expr>();
+ExprResult
+Sema::ActOnCXXThrow(SourceLocation OpLoc, Expr *Ex) {
if (Ex && !Ex->isTypeDependent() && CheckCXXThrowOperand(OpLoc, Ex))
return ExprError();
return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc));
@@ -400,8 +402,8 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
// the type from "array of T" or "function returning T" to "pointer to T"
// or "pointer to function returning T", [...]
if (E->getType().hasQualifiers())
- ImpCastExprToType(E, E->getType().getUnqualifiedType(), CastExpr::CK_NoOp,
- E->isLvalue(Context) == Expr::LV_Valid);
+ ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
+ CastCategory(E));
DefaultFunctionArrayConversion(E);
@@ -432,7 +434,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
InitializedEntity Entity =
InitializedEntity::InitializeException(ThrowLoc, E->getType(),
/*NRVO=*/false);
- OwningExprResult Res = PerformCopyInitialization(Entity,
+ ExprResult Res = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(E));
if (Res.isInvalid())
@@ -464,7 +466,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
return false;
}
-Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
+ExprResult 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.
@@ -483,8 +485,8 @@ Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
/// 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::OwningExprResult
-Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
+ExprResult
+Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep,
SourceLocation LParenLoc,
MultiExprArg exprs,
SourceLocation *CommaLocs,
@@ -532,19 +534,19 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
// corresponding cast expression.
//
if (NumExprs == 1) {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, BasePath,
/*FunctionalStyle=*/true))
return ExprError();
exprs.release();
- return Owned(new (Context) CXXFunctionalCastExpr(
+ return Owned(CXXFunctionalCastExpr::Create(Context,
Ty.getNonLValueExprType(Context),
- TInfo, TyBeginLoc, Kind,
- Exprs[0], BasePath,
- RParenLoc));
+ TInfo, TyBeginLoc, Kind,
+ Exprs[0], &BasePath,
+ RParenLoc));
}
if (Ty->isRecordType()) {
@@ -555,7 +557,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
: InitializationKind::CreateValue(TypeRange.getBegin(),
LParenLoc, RParenLoc);
InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
move(exprs));
// FIXME: Improve AST representation?
@@ -587,7 +589,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
/// or
/// @code ::new Foo(23, "hello") @endcode
/// For the interpretation of this heap of arguments, consult the base version.
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
SourceLocation PlacementRParen, SourceRange TypeIdParens,
@@ -643,13 +645,13 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
AllocType,
D.getSourceRange().getBegin(),
R,
- Owned(ArraySize),
+ ArraySize,
ConstructorLParen,
move(ConstructorArgs),
ConstructorRParen);
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen,
MultiExprArg PlacementArgs,
@@ -658,7 +660,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
QualType AllocType,
SourceLocation TypeLoc,
SourceRange TypeRange,
- ExprArg ArraySizeE,
+ Expr *ArraySize,
SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen) {
@@ -667,12 +669,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
// Per C++0x [expr.new]p5, the type being constructed may be a
// typedef of an array type.
- if (!ArraySizeE.get()) {
+ if (!ArraySize) {
if (const ConstantArrayType *Array
= Context.getAsConstantArrayType(AllocType)) {
- ArraySizeE = Owned(new (Context) IntegerLiteral(Array->getSize(),
- Context.getSizeType(),
- TypeRange.getEnd()));
+ ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
+ Context.getSizeType(),
+ TypeRange.getEnd());
AllocType = Array->getElementType();
}
}
@@ -681,13 +683,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
// C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral
// or enumeration type with a non-negative value."
- Expr *ArraySize = (Expr *)ArraySizeE.get();
if (ArraySize && !ArraySize->isTypeDependent()) {
QualType SizeType = ArraySize->getType();
- OwningExprResult ConvertedSize
- = ConvertToIntegralOrEnumerationType(StartLoc, move(ArraySizeE),
+ ExprResult ConvertedSize
+ = ConvertToIntegralOrEnumerationType(StartLoc, ArraySize,
PDiag(diag::err_array_size_not_integral),
PDiag(diag::err_array_size_incomplete_type)
<< ArraySize->getSourceRange(),
@@ -700,8 +701,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (ConvertedSize.isInvalid())
return ExprError();
- ArraySize = ConvertedSize.takeAs<Expr>();
- ArraySizeE = Owned(ArraySize);
+ ArraySize = ConvertedSize.take();
SizeType = ArraySize->getType();
if (!SizeType->isIntegralOrEnumerationType())
return ExprError();
@@ -716,8 +716,20 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
llvm::APInt::getNullValue(Value.getBitWidth()),
Value.isUnsigned()))
return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
- diag::err_typecheck_negative_array_size)
+ diag::err_typecheck_negative_array_size)
<< ArraySize->getSourceRange());
+
+ if (!AllocType->isDependentType()) {
+ unsigned ActiveSizeBits
+ = ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
+ if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
+ Diag(ArraySize->getSourceRange().getBegin(),
+ diag::err_array_too_large)
+ << Value.toString(10)
+ << ArraySize->getSourceRange();
+ return ExprError();
+ }
+ }
} else if (TypeIdParens.isValid()) {
// Can't have dynamic array size when the type-id is in parentheses.
Diag(ArraySize->getLocStart(), diag::ext_new_paren_array_nonconst)
@@ -730,7 +742,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
}
ImpCastExprToType(ArraySize, Context.getSizeType(),
- CastExpr::CK_IntegralCast);
+ CK_IntegralCast);
}
FunctionDecl *OperatorNew = 0;
@@ -768,7 +780,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
CXXConstructorDecl *Constructor = 0;
Expr **ConsArgs = (Expr**)ConstructorArgs.get();
unsigned NumConsArgs = ConstructorArgs.size();
- ASTOwningVector<&ActionBase::DeleteExpr> ConvertedConstructorArgs(*this);
+ ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
// Array 'new' can't have any initializers.
if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
@@ -798,7 +810,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, AllocType);
InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
- OwningExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
+ ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
move(ConstructorArgs));
if (FullInit.isInvalid())
return ExprError();
@@ -839,7 +851,6 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
PlacementArgs.release();
ConstructorArgs.release();
- ArraySizeE.release();
// FIXME: The TypeSourceInfo should also be included in CXXNewExpr.
return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
@@ -911,7 +922,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// We don't care about the actual value of this argument.
// FIXME: Should the Sema create the expression and embed it in the syntax
// tree? Or should the consumer just recalculate the value?
- IntegerLiteral Size(llvm::APInt::getNullValue(
+ IntegerLiteral Size(Context, llvm::APInt::getNullValue(
Context.Target.getPointerWidth(0)),
Context.getSizeType(),
SourceLocation());
@@ -929,9 +940,11 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
IsArray ? OO_Array_Delete : OO_Delete);
- if (AllocType->isRecordType() && !UseGlobal) {
+ QualType AllocElemType = Context.getBaseElementType(AllocType);
+
+ if (AllocElemType->isRecordType() && !UseGlobal) {
CXXRecordDecl *Record
- = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+ = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0],
AllocArgs.size(), Record, /*AllowMissing=*/true,
OperatorNew))
@@ -969,9 +982,9 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// the allocated type is not a class type or array thereof, the
// deallocation function’s name is looked up in the global scope.
LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
- if (AllocType->isRecordType() && !UseGlobal) {
+ if (AllocElemType->isRecordType() && !UseGlobal) {
CXXRecordDecl *RD
- = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+ = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
LookupQualifiedName(FoundDelete, RD);
}
if (FoundDelete.isAmbiguous())
@@ -1115,7 +1128,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
// Do the resolution.
OverloadCandidateSet::iterator Best;
- switch(BestViableFunction(Candidates, StartLoc, Best)) {
+ switch (Candidates.BestViableFunction(*this, StartLoc, Best)) {
case OR_Success: {
// Got one!
FunctionDecl *FnDecl = Best->Function;
@@ -1125,7 +1138,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
// Watch out for variadic allocator function.
unsigned NumArgsInFnDecl = FnDecl->getNumParams();
for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
- OwningExprResult Result
+ ExprResult Result
= PerformCopyInitialization(InitializedEntity::InitializeParameter(
FnDecl->getParamDecl(i)),
SourceLocation(),
@@ -1143,20 +1156,20 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
case OR_No_Viable_Function:
Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return true;
case OR_Ambiguous:
Diag(StartLoc, diag::err_ovl_ambiguous_call)
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_ViableCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
return true;
case OR_Deleted:
Diag(StartLoc, diag::err_ovl_deleted_call)
<< Best->Function->isDeleted()
<< Name << Range;
- PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+ Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return true;
}
assert(false && "Unreachable, bad result from BestViableFunction");
@@ -1199,11 +1212,11 @@ void Sema::DeclareGlobalNewDelete() {
// The "std::bad_alloc" class has not yet been declared, so build it
// implicitly.
StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class,
- getStdNamespace(),
+ getOrCreateStdNamespace(),
SourceLocation(),
&PP.getIdentifierTable().get("bad_alloc"),
SourceLocation(), 0);
- StdBadAlloc->setImplicit(true);
+ getStdBadAlloc()->setImplicit(true);
}
GlobalNewDeleteDeclared = true;
@@ -1245,8 +1258,11 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
Context.getCanonicalType(
Func->getParamDecl(0)->getType().getUnqualifiedType());
// FIXME: Do we need to check for default arguments here?
- if (Func->getNumParams() == 1 && InitialParamType == Argument)
+ if (Func->getNumParams() == 1 && InitialParamType == Argument) {
+ if(AddMallocAttr && !Func->hasAttr<MallocAttr>())
+ Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
return;
+ }
}
}
}
@@ -1257,7 +1273,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
Name.getCXXOverloadedOperator() == OO_Array_New);
if (HasBadAllocExceptionSpec) {
assert(StdBadAlloc && "Must have std::bad_alloc declared");
- BadAllocType = Context.getTypeDeclType(StdBadAlloc);
+ BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
}
QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0,
@@ -1267,23 +1283,23 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
FunctionType::ExtInfo());
FunctionDecl *Alloc =
FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
- FnType, /*TInfo=*/0, FunctionDecl::None,
- FunctionDecl::None, false, true);
+ FnType, /*TInfo=*/0, SC_None,
+ SC_None, false, true);
Alloc->setImplicit();
if (AddMallocAttr)
- Alloc->addAttr(::new (Context) MallocAttr());
+ Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
0, Argument, /*TInfo=*/0,
- VarDecl::None,
- VarDecl::None, 0);
+ SC_None,
+ SC_None, 0);
Alloc->setParams(&Param, 1);
// FIXME: Also add this declaration to the IdentifierResolver, but
// make sure it is at the end of the chain to coincide with the
// global scope.
- ((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
+ Context.getTranslationUnitDecl()->addDecl(Alloc);
}
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
@@ -1298,15 +1314,37 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
Found.suppressDiagnostics();
+ llvm::SmallVector<DeclAccessPair,4> Matches;
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
F != FEnd; ++F) {
- if (CXXMethodDecl *Delete = dyn_cast<CXXMethodDecl>(*F))
- if (Delete->isUsualDeallocationFunction()) {
- Operator = Delete;
- CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
- F.getPair());
- return false;
- }
+ NamedDecl *ND = (*F)->getUnderlyingDecl();
+
+ // Ignore template operator delete members from the check for a usual
+ // deallocation function.
+ if (isa<FunctionTemplateDecl>(ND))
+ continue;
+
+ if (cast<CXXMethodDecl>(ND)->isUsualDeallocationFunction())
+ Matches.push_back(F.getPair());
+ }
+
+ // There's exactly one suitable operator; pick it.
+ if (Matches.size() == 1) {
+ Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
+ CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
+ Matches[0]);
+ return false;
+
+ // We found multiple suitable operators; complain about the ambiguity.
+ } else if (!Matches.empty()) {
+ Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
+ << Name << RD;
+
+ for (llvm::SmallVectorImpl<DeclAccessPair>::iterator
+ F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
+ Diag((*F)->getUnderlyingDecl()->getLocation(),
+ diag::note_member_declared_here) << Name;
+ return true;
}
// We did find operator delete/operator delete[] declarations, but
@@ -1316,10 +1354,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
<< Name << RD;
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
- F != FEnd; ++F) {
- Diag((*F)->getLocation(), diag::note_member_declared_here)
- << Name;
- }
+ F != FEnd; ++F)
+ Diag((*F)->getUnderlyingDecl()->getLocation(),
+ diag::note_member_declared_here) << Name;
return true;
}
@@ -1344,9 +1381,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
/// @code ::delete ptr; @endcode
/// or
/// @code delete [] ptr; @endcode
-Action::OwningExprResult
+ExprResult
Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
- bool ArrayForm, ExprArg Operand) {
+ bool ArrayForm, Expr *Ex) {
// C++ [expr.delete]p1:
// 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.
@@ -1355,11 +1392,14 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
FunctionDecl *OperatorDelete = 0;
- Expr *Ex = (Expr *)Operand.get();
if (!Ex->isTypeDependent()) {
QualType Type = Ex->getType();
if (const RecordType *Record = Type->getAs<RecordType>()) {
+ if (RequireCompleteType(StartLoc, Type,
+ PDiag(diag::err_delete_incomplete_class_type)))
+ return ExprError();
+
llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
@@ -1378,18 +1418,16 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
QualType ConvType = Conv->getConversionType().getNonReferenceType();
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
- if (ConvPtrType->getPointeeType()->isObjectType())
+ if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
ObjectPtrConversions.push_back(Conv);
}
if (ObjectPtrConversions.size() == 1) {
// We have a single conversion to a pointer-to-object type. Perform
// that conversion.
// TODO: don't redo the conversion calculation.
- Operand.release();
if (!PerformImplicitConversion(Ex,
ObjectPtrConversions.front()->getConversionType(),
AA_Converting)) {
- Operand = Owned(Ex);
Type = Ex->getType();
}
}
@@ -1428,16 +1466,13 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
// (5.2.11) of the pointer expression before it is used as the operand
// of the delete-expression. ]
ImpCastExprToType(Ex, Context.getPointerType(Context.VoidTy),
- CastExpr::CK_NoOp);
-
- // Update the operand.
- Operand.take();
- Operand = ExprArg(*this, Ex);
+ CK_NoOp);
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
ArrayForm ? OO_Array_Delete : OO_Delete);
- if (const RecordType *RT = Pointee->getAs<RecordType>()) {
+ QualType PointeeElem = Context.getBaseElementType(Pointee);
+ if (const RecordType *RT = PointeeElem->getAs<RecordType>()) {
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
if (!UseGlobal &&
@@ -1465,14 +1500,13 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
// FIXME: Check access and ambiguity of operator delete and destructor.
}
- Operand.release();
return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
OperatorDelete, Ex, StartLoc));
}
/// \brief Check the use of the given variable as a C++ condition in an if,
/// while, do-while, or switch statement.
-Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
+ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
SourceLocation StmtLoc,
bool ConvertToBoolean) {
QualType T = ConditionVar->getType();
@@ -1491,10 +1525,8 @@ Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar,
ConditionVar->getLocation(),
ConditionVar->getType().getNonReferenceType());
- if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc)) {
- Condition->Destroy(Context);
+ if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc))
return ExprError();
- }
return Owned(Condition);
}
@@ -1543,34 +1575,33 @@ Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
return false;
}
-static Sema::OwningExprResult BuildCXXCastArgument(Sema &S,
- SourceLocation CastLoc,
- QualType Ty,
- CastExpr::CastKind Kind,
- CXXMethodDecl *Method,
- Sema::ExprArg Arg) {
- Expr *From = Arg.takeAs<Expr>();
-
+static ExprResult BuildCXXCastArgument(Sema &S,
+ SourceLocation CastLoc,
+ QualType Ty,
+ CastKind Kind,
+ CXXMethodDecl *Method,
+ Expr *From) {
switch (Kind) {
default: assert(0 && "Unhandled cast kind!");
- case CastExpr::CK_ConstructorConversion: {
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+ case CK_ConstructorConversion: {
+ ASTOwningVector<Expr*> ConstructorArgs(S);
if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method),
- Sema::MultiExprArg(S, (void **)&From, 1),
+ MultiExprArg(&From, 1),
CastLoc, ConstructorArgs))
- return S.ExprError();
+ return ExprError();
- Sema::OwningExprResult Result =
+ ExprResult Result =
S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
- move_arg(ConstructorArgs));
+ move_arg(ConstructorArgs),
+ /*ZeroInit*/ false, CXXConstructExpr::CK_Complete);
if (Result.isInvalid())
- return S.ExprError();
+ return ExprError();
return S.MaybeBindToTemporary(Result.takeAs<Expr>());
}
- case CastExpr::CK_UserDefinedConversion: {
+ case CK_UserDefinedConversion: {
assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
// Create an implicit call expr that calls it.
@@ -1601,10 +1632,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
case ImplicitConversionSequence::UserDefinedConversion: {
FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
- CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+ CastKind CastKind = CK_Unknown;
QualType BeforeToType;
if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
- CastKind = CastExpr::CK_UserDefinedConversion;
+ CastKind = CK_UserDefinedConversion;
// If the user-defined conversion is specified by a conversion function,
// the initial standard conversion sequence converts the source type to
@@ -1612,7 +1643,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
BeforeToType = Context.getTagDeclType(Conv->getParent());
} else if (const CXXConstructorDecl *Ctor =
dyn_cast<CXXConstructorDecl>(FD)) {
- CastKind = CastExpr::CK_ConstructorConversion;
+ CastKind = CK_ConstructorConversion;
// Do no conversion if dealing with ... for the first conversion.
if (!ICS.UserDefined.EllipsisConversion) {
// If the user-defined conversion is specified by a constructor, the
@@ -1631,12 +1662,12 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
return true;
}
- OwningExprResult CastArg
+ ExprResult CastArg
= BuildCXXCastArgument(*this,
From->getLocStart(),
ToType.getNonReferenceType(),
CastKind, cast<CXXMethodDecl>(FD),
- Owned(From));
+ From);
if (CastArg.isInvalid())
return true;
@@ -1648,7 +1679,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
}
case ImplicitConversionSequence::AmbiguousConversion:
- DiagnoseAmbiguousConversion(ICS, From->getExprLoc(),
+ ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(),
PDiag(diag::err_typecheck_ambiguous_condition)
<< From->getSourceRange());
return true;
@@ -1685,25 +1716,29 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
// FIXME: When can ToType be a reference type?
assert(!ToType->isReferenceType());
if (SCS.Second == ICK_Derived_To_Base) {
- ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
+ ASTOwningVector<Expr*> ConstructorArgs(*this);
if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor),
- MultiExprArg(*this, (void **)&From, 1),
+ MultiExprArg(*this, &From, 1),
/*FIXME:ConstructLoc*/SourceLocation(),
ConstructorArgs))
return true;
- OwningExprResult FromResult =
+ ExprResult FromResult =
BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
ToType, SCS.CopyConstructor,
- move_arg(ConstructorArgs));
+ move_arg(ConstructorArgs),
+ /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete);
if (FromResult.isInvalid())
return true;
From = FromResult.takeAs<Expr>();
return false;
}
- OwningExprResult FromResult =
+ ExprResult FromResult =
BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
ToType, SCS.CopyConstructor,
- MultiExprArg(*this, (void**)&From, 1));
+ MultiExprArg(*this, &From, 1),
+ /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete);
if (FromResult.isInvalid())
return true;
@@ -1736,12 +1771,12 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
case ICK_Array_To_Pointer:
FromType = Context.getArrayDecayedType(FromType);
- ImpCastExprToType(From, FromType, CastExpr::CK_ArrayToPointerDecay);
+ ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay);
break;
case ICK_Function_To_Pointer:
FromType = Context.getPointerType(FromType);
- ImpCastExprToType(From, FromType, CastExpr::CK_FunctionToPointerDecay);
+ ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay);
break;
default:
@@ -1766,33 +1801,33 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
return true;
ImpCastExprToType(From, Context.getNoReturnType(From->getType(), false),
- CastExpr::CK_NoOp);
+ CK_NoOp);
break;
case ICK_Integral_Promotion:
case ICK_Integral_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(From, ToType, CK_IntegralCast);
break;
case ICK_Floating_Promotion:
case ICK_Floating_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_FloatingCast);
+ ImpCastExprToType(From, ToType, CK_FloatingCast);
break;
case ICK_Complex_Promotion:
case ICK_Complex_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+ ImpCastExprToType(From, ToType, CK_Unknown);
break;
case ICK_Floating_Integral:
if (ToType->isRealFloatingType())
- ImpCastExprToType(From, ToType, CastExpr::CK_IntegralToFloating);
+ ImpCastExprToType(From, ToType, CK_IntegralToFloating);
else
- ImpCastExprToType(From, ToType, CastExpr::CK_FloatingToIntegral);
+ ImpCastExprToType(From, ToType, CK_FloatingToIntegral);
break;
case ICK_Compatible_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_NoOp);
+ ImpCastExprToType(From, ToType, CK_NoOp);
break;
case ICK_Pointer_Conversion: {
@@ -1805,36 +1840,36 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
}
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
return true;
- ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+ ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
break;
}
case ICK_Pointer_Member: {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckMemberPointerConversion(From, ToType, Kind, BasePath,
IgnoreBaseAccess))
return true;
if (CheckExceptionSpecCompatibility(From, ToType))
return true;
- ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+ ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
break;
}
case ICK_Boolean_Conversion: {
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+ CastKind Kind = CK_Unknown;
if (FromType->isMemberPointerType())
- Kind = CastExpr::CK_MemberPointerToBoolean;
+ Kind = CK_MemberPointerToBoolean;
ImpCastExprToType(From, Context.BoolTy, Kind);
break;
}
case ICK_Derived_To_Base: {
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(From->getType(),
ToType.getNonReferenceType(),
From->getLocStart(),
@@ -1843,24 +1878,22 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
IgnoreBaseAccess))
return true;
- ImpCastExprToType(From, ToType.getNonReferenceType(),
- CastExpr::CK_DerivedToBase,
- /*isLvalue=*/(From->getType()->isRecordType() &&
- From->isLvalue(Context) == Expr::LV_Valid),
- BasePath);
+ ImpCastExprToType(From, ToType.getNonReferenceType(),
+ CK_DerivedToBase, CastCategory(From),
+ &BasePath);
break;
}
case ICK_Vector_Conversion:
- ImpCastExprToType(From, ToType, CastExpr::CK_BitCast);
+ ImpCastExprToType(From, ToType, CK_BitCast);
break;
case ICK_Vector_Splat:
- ImpCastExprToType(From, ToType, CastExpr::CK_VectorSplat);
+ ImpCastExprToType(From, ToType, CK_VectorSplat);
break;
case ICK_Complex_Real:
- ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+ ImpCastExprToType(From, ToType, CK_Unknown);
break;
case ICK_Lvalue_To_Rvalue:
@@ -1877,18 +1910,21 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
// Nothing to do.
break;
- case ICK_Qualification:
- // FIXME: Not sure about lvalue vs rvalue here in the presence of rvalue
- // references.
+ case ICK_Qualification: {
+ // The qualification keeps the category of the inner expression, unless the
+ // target type isn't a reference.
+ ExprValueKind VK = ToType->isReferenceType() ?
+ CastCategory(From) : VK_RValue;
ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
- CastExpr::CK_NoOp, ToType->isLValueReferenceType());
+ CK_NoOp, VK);
if (SCS.DeprecatedStringLiteralToCharPtr)
Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
<< ToType.getNonReferenceType();
break;
-
+ }
+
default:
assert(false && "Improper third standard conversion");
break;
@@ -1897,10 +1933,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
return false;
}
-Sema::OwningExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
SourceLocation KWLoc,
SourceLocation LParen,
- TypeTy *Ty,
+ ParsedType Ty,
SourceLocation RParen) {
QualType T = GetTypeFromParser(Ty);
@@ -1974,12 +2010,12 @@ QualType Sema::CheckPointerToMemberOperands(
}
// Cast LHS to type of use.
QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
- bool isLValue = !isIndirect && lex->isLvalue(Context) == Expr::LV_Valid;
-
- CXXBaseSpecifierArray BasePath;
+ ExprValueKind VK =
+ isIndirect ? VK_RValue : CastCategory(lex);
+
+ CXXCastPath BasePath;
BuildBasePathArray(Paths, BasePath);
- ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, isLValue,
- BasePath);
+ ImpCastExprToType(lex, UseType, CK_DerivedToBase, VK, &BasePath);
}
if (isa<CXXScalarValueInitExpr>(rex->IgnoreParens())) {
@@ -2108,7 +2144,7 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS,
Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet);
OverloadCandidateSet::iterator Best;
- switch (Self.BestViableFunction(CandidateSet, Loc, Best)) {
+ switch (CandidateSet.BestViableFunction(Self, Loc, Best)) {
case OR_Success:
// We found a match. Perform the conversions on the arguments and move on.
if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
@@ -2146,8 +2182,7 @@ static bool ConvertForConditional(Sema &Self, Expr *&E, QualType T) {
InitializationKind Kind = InitializationKind::CreateCopy(E->getLocStart(),
SourceLocation());
InitializationSequence InitSeq(Self, Entity, Kind, &E, 1);
- Sema::OwningExprResult Result = InitSeq.Perform(Self, Entity, Kind,
- Sema::MultiExprArg(Self, (void **)&E, 1));
+ ExprResult Result = InitSeq.Perform(Self, Entity, Kind, MultiExprArg(&E, 1));
if (Result.isInvalid())
return true;
@@ -2286,13 +2321,13 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (LTy->isRecordType()) {
// The operands have class type. Make a temporary copy.
InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
- OwningExprResult LHSCopy = PerformCopyInitialization(Entity,
+ ExprResult LHSCopy = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(LHS));
if (LHSCopy.isInvalid())
return QualType();
- OwningExprResult RHSCopy = PerformCopyInitialization(Entity,
+ ExprResult RHSCopy = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(RHS));
if (RHSCopy.isInvalid())
@@ -2385,16 +2420,16 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// the type of the other operand.
if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
if (T2->isMemberPointerType())
- ImpCastExprToType(E1, T2, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(E1, T2, CK_NullToMemberPointer);
else
- ImpCastExprToType(E1, T2, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(E1, T2, CK_IntegralToPointer);
return T2;
}
if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
if (T1->isMemberPointerType())
- ImpCastExprToType(E2, T1, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(E2, T1, CK_NullToMemberPointer);
else
- ImpCastExprToType(E2, T1, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(E2, T1, CK_IntegralToPointer);
return T1;
}
@@ -2528,15 +2563,15 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
}
// Convert E1 to Composite1
- OwningExprResult E1Result
- = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E1,1));
+ ExprResult E1Result
+ = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E1,1));
if (E1Result.isInvalid())
return QualType();
E1 = E1Result.takeAs<Expr>();
// Convert E2 to Composite1
- OwningExprResult E2Result
- = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E2,1));
+ ExprResult E2Result
+ = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E2,1));
if (E2Result.isInvalid())
return QualType();
E2 = E2Result.takeAs<Expr>();
@@ -2553,15 +2588,15 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
return QualType();
// Convert E1 to Composite2
- OwningExprResult E1Result
- = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E1, 1));
+ ExprResult E1Result
+ = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E1, 1));
if (E1Result.isInvalid())
return QualType();
E1 = E1Result.takeAs<Expr>();
// Convert E2 to Composite2
- OwningExprResult E2Result
- = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E2, 1));
+ ExprResult E2Result
+ = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E2, 1));
if (E2Result.isInvalid())
return QualType();
E2 = E2Result.takeAs<Expr>();
@@ -2569,7 +2604,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
return Composite2;
}
-Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
+ExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (!Context.getLangOptions().CPlusPlus)
return Owned(E);
@@ -2579,34 +2614,22 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (!RT)
return Owned(E);
- // If this is the result of a call expression, our source might
- // actually be a reference, in which case we shouldn't bind.
+ // If this is the result of a call or an Objective-C message send expression,
+ // our source might actually be a reference, in which case we shouldn't bind.
if (CallExpr *CE = dyn_cast<CallExpr>(E)) {
- QualType Ty = CE->getCallee()->getType();
- if (const PointerType *PT = Ty->getAs<PointerType>())
- Ty = PT->getPointeeType();
- else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
- Ty = BPT->getPointeeType();
-
- const FunctionType *FTy = Ty->getAs<FunctionType>();
- if (FTy->getResultType()->isReferenceType())
+ if (CE->getCallReturnType()->isReferenceType())
return Owned(E);
+ } else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+ if (const ObjCMethodDecl *MD = ME->getMethodDecl()) {
+ if (MD->getResultType()->isReferenceType())
+ return Owned(E);
+ }
}
- else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
- QualType Ty = ME->getType();
- if (const PointerType *PT = Ty->getAs<PointerType>())
- Ty = PT->getPointeeType();
- else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
- Ty = BPT->getPointeeType();
- if (Ty->isReferenceType())
- return Owned(E);
- }
-
// That should be enough to guarantee that this type is complete.
// If it has a trivial destructor, we can avoid the extra copy.
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (RD->hasTrivialDestructor())
+ if (RD->isInvalidDecl() || RD->hasTrivialDestructor())
return Owned(E);
CXXTemporary *Temp = CXXTemporary::Create(Context, LookupDestructor(RD));
@@ -2641,8 +2664,8 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) {
return E;
}
-Sema::OwningExprResult
-Sema::MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr) {
+ExprResult
+Sema::MaybeCreateCXXExprWithTemporaries(ExprResult SubExpr) {
if (SubExpr.isInvalid())
return ExprError();
@@ -2665,17 +2688,16 @@ FullExpr Sema::CreateFullExpr(Expr *SubExpr) {
return E;
}
-Sema::OwningExprResult
-Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
- tok::TokenKind OpKind, TypeTy *&ObjectType,
+ExprResult
+Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
+ tok::TokenKind OpKind, ParsedType &ObjectType,
bool &MayBePseudoDestructor) {
// Since this might be a postfix expression, get rid of ParenListExprs.
- Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+ if (Result.isInvalid()) return ExprError();
+ Base = Result.get();
- Expr *BaseExpr = (Expr*)Base.get();
- assert(BaseExpr && "no record expansion");
-
- QualType BaseType = BaseExpr->getType();
+ QualType BaseType = Base->getType();
MayBePseudoDestructor = false;
if (BaseType->isDependentType()) {
// If we have a pointer to a dependent type and are using the -> operator,
@@ -2685,9 +2707,9 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (const PointerType *Ptr = BaseType->getAs<PointerType>())
BaseType = Ptr->getPointeeType();
- ObjectType = BaseType.getAsOpaquePtr();
+ ObjectType = ParsedType::make(BaseType);
MayBePseudoDestructor = true;
- return move(Base);
+ return Owned(Base);
}
// C++ [over.match.oper]p8:
@@ -2700,13 +2722,13 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
CTypes.insert(Context.getCanonicalType(BaseType));
while (BaseType->isRecordType()) {
- Base = BuildOverloadedArrowExpr(S, move(Base), OpLoc);
- BaseExpr = (Expr*)Base.get();
- if (BaseExpr == NULL)
+ Result = BuildOverloadedArrowExpr(S, Base, OpLoc);
+ if (Result.isInvalid())
return ExprError();
- if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(BaseExpr))
+ Base = Result.get();
+ if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(Base))
Locations.push_back(OpCall->getDirectCallee()->getLocation());
- BaseType = BaseExpr->getType();
+ BaseType = Base->getType();
CanQualType CBaseType = Context.getCanonicalType(BaseType);
if (!CTypes.insert(CBaseType)) {
Diag(OpLoc, diag::err_operator_arrow_circular);
@@ -2731,9 +2753,9 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
//
// This also indicates that we should be parsing a
// pseudo-destructor-name.
- ObjectType = 0;
+ ObjectType = ParsedType();
MayBePseudoDestructor = true;
- return move(Base);
+ return Owned(Base);
}
// The object type must be complete (or dependent).
@@ -2747,27 +2769,26 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
// unqualified-id, and the type of the object expression is of a class
// type C (or of pointer to a class type C), the unqualified-id is looked
// up in the scope of class C. [...]
- ObjectType = BaseType.getAsOpaquePtr();
+ ObjectType = ParsedType::make(BaseType);
return move(Base);
}
-Sema::OwningExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
- ExprArg MemExpr) {
- Expr *E = (Expr *) MemExpr.get();
+ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
+ Expr *MemExpr) {
SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(NameLoc);
- Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
- << isa<CXXPseudoDestructorExpr>(E)
+ Diag(MemExpr->getLocStart(), diag::err_dtor_expr_without_call)
+ << isa<CXXPseudoDestructorExpr>(MemExpr)
<< FixItHint::CreateInsertion(ExpectedLParenLoc, "()");
return ActOnCallExpr(/*Scope*/ 0,
- move(MemExpr),
+ MemExpr,
/*LPLoc*/ ExpectedLParenLoc,
- Sema::MultiExprArg(*this, 0, 0),
+ MultiExprArg(),
/*CommaLocs*/ 0,
/*RPLoc*/ ExpectedLParenLoc);
}
-Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
+ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
const CXXScopeSpec &SS,
@@ -2782,12 +2803,11 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
// The left-hand side of the dot operator shall be of scalar type. The
// left-hand side of the arrow operator shall be of pointer to scalar type.
// This scalar type is the object type.
- Expr *BaseE = (Expr *)Base.get();
- QualType ObjectType = BaseE->getType();
+ QualType ObjectType = Base->getType();
if (OpKind == tok::arrow) {
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
ObjectType = Ptr->getPointeeType();
- } else if (!BaseE->isTypeDependent()) {
+ } else if (!Base->isTypeDependent()) {
// The user wrote "p->" when she probably meant "p."; fix it.
Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
<< ObjectType << true
@@ -2801,7 +2821,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) {
Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
- << ObjectType << BaseE->getSourceRange();
+ << ObjectType << Base->getSourceRange();
return ExprError();
}
@@ -2815,7 +2835,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
if (!DestructedType->isDependentType() && !ObjectType->isDependentType() &&
!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
- << ObjectType << DestructedType << BaseE->getSourceRange()
+ << ObjectType << DestructedType << Base->getSourceRange()
<< DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
// Recover by setting the destructed type to the object type.
@@ -2840,7 +2860,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(),
diag::err_pseudo_dtor_type_mismatch)
- << ObjectType << ScopeType << BaseE->getSourceRange()
+ << ObjectType << ScopeType << Base->getSourceRange()
<< ScopeTypeInfo->getTypeLoc().getLocalSourceRange();
ScopeType = QualType();
@@ -2848,25 +2868,22 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
}
}
- OwningExprResult Result
- = Owned(new (Context) CXXPseudoDestructorExpr(Context,
- Base.takeAs<Expr>(),
- OpKind == tok::arrow,
- OpLoc,
- (NestedNameSpecifier *) SS.getScopeRep(),
- SS.getRange(),
- ScopeTypeInfo,
- CCLoc,
- TildeLoc,
- Destructed));
+ Expr *Result
+ = new (Context) CXXPseudoDestructorExpr(Context, Base,
+ OpKind == tok::arrow, OpLoc,
+ SS.getScopeRep(), SS.getRange(),
+ ScopeTypeInfo,
+ CCLoc,
+ TildeLoc,
+ Destructed);
if (HasTrailingLParen)
- return move(Result);
+ return Owned(Result);
- return DiagnoseDtorReference(Destructed.getLocation(), move(Result));
+ return DiagnoseDtorReference(Destructed.getLocation(), Result);
}
-Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
CXXScopeSpec &SS,
@@ -2882,13 +2899,11 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
"Invalid second type name in pseudo-destructor");
- Expr *BaseE = (Expr *)Base.get();
-
// C++ [expr.pseudo]p2:
// The left-hand side of the dot operator shall be of scalar type. The
// left-hand side of the arrow operator shall be of pointer to scalar type.
// This scalar type is the object type.
- QualType ObjectType = BaseE->getType();
+ QualType ObjectType = Base->getType();
if (OpKind == tok::arrow) {
if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
ObjectType = Ptr->getPointeeType();
@@ -2906,12 +2921,12 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
// Compute the object type that we should use for name lookup purposes. Only
// record types and dependent types matter.
- void *ObjectTypePtrForLookup = 0;
+ ParsedType ObjectTypePtrForLookup;
if (!SS.isSet()) {
- ObjectTypePtrForLookup = const_cast<RecordType*>(
- ObjectType->getAs<RecordType>());
- if (!ObjectTypePtrForLookup && ObjectType->isDependentType())
- ObjectTypePtrForLookup = Context.DependentTy.getAsOpaquePtr();
+ if (const Type *T = ObjectType->getAs<RecordType>())
+ ObjectTypePtrForLookup = ParsedType::make(QualType(T, 0));
+ else if (ObjectType->isDependentType())
+ ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
}
// Convert the name of the type being destructed (following the ~) into a
@@ -2920,9 +2935,9 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
TypeSourceInfo *DestructedTypeInfo = 0;
PseudoDestructorTypeStorage Destructed;
if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
- TypeTy *T = getTypeName(*SecondTypeName.Identifier,
- SecondTypeName.StartLocation,
- S, &SS, true, ObjectTypePtrForLookup);
+ ParsedType T = getTypeName(*SecondTypeName.Identifier,
+ SecondTypeName.StartLocation,
+ S, &SS, true, ObjectTypePtrForLookup);
if (!T &&
((SS.isSet() && !computeDeclContext(SS, false)) ||
(!SS.isSet() && ObjectType->isDependentType()))) {
@@ -2949,7 +2964,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
- TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+ TypeResult T = ActOnTemplateIdType(TemplateId->Template,
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
@@ -2976,9 +2991,9 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
FirstTypeName.Identifier) {
if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
- TypeTy *T = getTypeName(*FirstTypeName.Identifier,
- FirstTypeName.StartLocation,
- S, &SS, false, ObjectTypePtrForLookup);
+ ParsedType T = getTypeName(*FirstTypeName.Identifier,
+ FirstTypeName.StartLocation,
+ S, &SS, false, ObjectTypePtrForLookup);
if (!T) {
Diag(FirstTypeName.StartLocation,
diag::err_pseudo_dtor_destructor_non_type)
@@ -2997,7 +3012,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
- TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+ TypeResult T = ActOnTemplateIdType(TemplateId->Template,
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
@@ -3015,7 +3030,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
FirstTypeName.StartLocation);
- return BuildPseudoDestructorExpr(move(Base), OpLoc, OpKind, SS,
+ return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS,
ScopeTypeInfo, CCLoc, TildeLoc,
Destructed, HasTrailingLParen);
}
@@ -3028,7 +3043,7 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
MemberExpr *ME =
- new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
+ new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
SourceLocation(), Method->getType());
QualType ResultType = Method->getCallResultType();
MarkDeclarationReferenced(Exp->getLocStart(), Method);
@@ -3038,12 +3053,7 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
return CE;
}
-Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
- Expr *FullExpr = Arg.takeAs<Expr>();
- if (FullExpr)
- FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr);
- else
- return ExprError();
-
- return Owned(FullExpr);
+ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
+ if (!FullExpr) return ExprError();
+ return MaybeCreateCXXExprWithTemporaries(FullExpr);
}