/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in: /// @code ::delete ptr; @endcode /// or /// @code delete [] ptr; @endcode Action::OwningExprResult Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, 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.get(); if (!Ex->isTypeDependent()) { QualType Type = Ex->getType(); if (Type->isRecordType()) { // FIXME: Find that one conversion function and amend the type. } if (!Type->isPointerType()) return ExprError(Diag(StartLoc, diag::err_delete_operand) << Type << Ex->getSourceRange()); QualType Pointee = Type->getAsPointerType()->getPointeeType(); if (Pointee->isFunctionType() || Pointee->isVoidType()) return ExprError(Diag(StartLoc, diag::err_delete_operand) << Type << Ex->getSourceRange()); else if (!Pointee->isDependentType() && RequireCompleteType(StartLoc, Pointee, diag::warn_delete_incomplete, Ex->getSourceRange())) return ExprError(); // FIXME: Look up the correct operator delete overload and pass a pointer // along. // FIXME: Check access and ambiguity of operator delete and destructor. } 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::OwningExprResult Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc, Declarator &D, SourceLocation EqualLoc, ExprArg AssignExprVal) { assert(AssignExprVal.get() && "Null assignment expression"); // C++ 6.4p2: // The declarator shall not specify a function or an array. // The type-specifier-seq shall not contain typedef and shall not declare a // new class or enumeration. assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && "Parser allowed 'typedef' as storage class of condition decl."); QualType Ty = GetTypeForDeclarator(D, S); 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 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); } else if (const RecordType *RT = Ty->getAsRecordType()) { RecordDecl *RD = RT->getDecl(); // The type-specifier-seq shall not declare a new class... if (RD->isDefinition() && (RD->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(RD)))) Diag(RD->getLocation(), diag::err_type_defined_in_condition); } else if (const EnumType *ET = Ty->getAsEnumType()) { EnumDecl *ED = ET->getDecl(); // ...or enumeration. if (ED->isDefinition() && (ED->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(ED)))) Diag(ED->getLocation(), diag::err_type_defined_in_condition); } DeclPtrTy Dcl = ActOnDeclarator(S, D, DeclPtrTy()); if (!Dcl) return ExprError(); AddInitializerToDecl(Dcl, move(AssignExprVal)); // Mark this variable as one that is declared within a conditional. // We know that the decl had to be a VarDecl because that is the only type of // decl that can be assigned and the grammar requires an '='. VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>()); VD->setDeclaredInCondition(true); return Owned(new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc, VD)); }
// ActOnInstanceMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions // is obtained from Sel.getNumArgs(). Sema::OwningExprResult Sema::ActOnInstanceMessage(Scope *S, ExprArg ReceiverE, Selector Sel, SourceLocation LBracLoc, SourceLocation SelectorLoc, SourceLocation RBracLoc, MultiExprArg Args) { Expr *Receiver = static_cast<Expr *>(ReceiverE.get()); if (!Receiver) return ExprError(); return BuildInstanceMessage(move(ReceiverE), Receiver->getType(), /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0, LBracLoc, RBracLoc, move(Args)); }
/// ActOnCXXThrow - Parse throw expressions. Action::OwningExprResult Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprArg E) { return Owned(new (Context) CXXThrowExpr((Expr*)E.release(), Context.VoidTy, OpLoc)); }