From 6f28289aca5bf15feb49b95e73f80cf9af99cdb3 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Tue, 11 Nov 2008 17:56:53 +0000 Subject: [PATCH] Introduce a single AST node SizeOfAlignOfExpr for all sizeof and alignof expressions, both of values and types. llvm-svn: 59057 --- clang/Driver/PrintParserCallbacks.cpp | 5 +- clang/Driver/RewriteObjC.cpp | 7 +- clang/include/clang/AST/Expr.h | 52 +++++--- clang/include/clang/AST/StmtNodes.def | 2 +- clang/include/clang/AST/StmtVisitor.h | 3 - .../Analysis/PathSensitive/GRExprEngine.h | 6 +- clang/include/clang/Parse/Action.h | 5 +- clang/lib/AST/CFG.cpp | 30 ++--- clang/lib/AST/Expr.cpp | 113 ++++++++---------- clang/lib/AST/ExprConstant.cpp | 24 ++-- clang/lib/AST/StmtDumper.cpp | 7 +- clang/lib/AST/StmtPrinter.cpp | 15 ++- clang/lib/AST/StmtSerialization.cpp | 25 ++-- clang/lib/Analysis/GRExprEngine.cpp | 48 ++------ clang/lib/Analysis/LiveVariables.cpp | 1 - clang/lib/Analysis/UninitializedValues.cpp | 3 - clang/lib/CodeGen/CGExprComplex.cpp | 2 +- clang/lib/CodeGen/CGExprConstant.cpp | 10 +- clang/lib/CodeGen/CGExprScalar.cpp | 24 ++-- clang/lib/Parse/ParseExpr.cpp | 13 +- clang/lib/Sema/Sema.h | 10 +- clang/lib/Sema/SemaDecl.cpp | 12 +- clang/lib/Sema/SemaExpr.cpp | 62 +++++----- 23 files changed, 212 insertions(+), 267 deletions(-) diff --git a/clang/Driver/PrintParserCallbacks.cpp b/clang/Driver/PrintParserCallbacks.cpp index adf3bed0d02a..0048a6d459b1 100644 --- a/clang/Driver/PrintParserCallbacks.cpp +++ b/clang/Driver/PrintParserCallbacks.cpp @@ -473,9 +473,8 @@ namespace { return 0; } virtual ExprResult - ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof, - SourceLocation LParenLoc, TypeTy *Ty, - SourceLocation RParenLoc) { + ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, + void *TyOrEx, const SourceRange &ArgRange) { llvm::cout << __FUNCTION__ << "\n"; return 0; } diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index 35d7cc8e1fa7..9d78c42d0253 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/Driver/RewriteObjC.cpp @@ -2254,9 +2254,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { FT->getResultType(), SourceLocation()); // Build sizeof(returnType) - SizeOfAlignOfTypeExpr *sizeofExpr = new SizeOfAlignOfTypeExpr(true, - returnType, Context->getSizeType(), - SourceLocation(), SourceLocation()); + SizeOfAlignOfExpr *sizeofExpr = new SizeOfAlignOfExpr(true, true, + returnType.getAsOpaquePtr(), + Context->getSizeType(), + SourceLocation(), SourceLocation()); // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases. // For X86 it is more complicated and some kind of target specific routine diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 6023c6803d01..efab1a14e140 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -431,8 +431,8 @@ public: }; -/// UnaryOperator - This represents the unary-expression's (except sizeof of -/// types), the postinc/postdec operators from postfix-expression, and various +/// UnaryOperator - This represents the unary-expression's (except sizeof and +/// alignof), the postinc/postdec operators from postfix-expression, and various /// extensions. /// /// Notes on various nodes: @@ -454,7 +454,6 @@ public: AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators. Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators. Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators. - SizeOf, AlignOf, // [C99 6.5.3.4] Sizeof (expr, not type) operator. Real, Imag, // "__real expr"/"__imag expr" Extension. Extension, // __extension__ marker. OffsetOf // __builtin_offsetof @@ -484,7 +483,6 @@ public: bool isPostfix() const { return isPostfix(Opc); } bool isIncrementOp() const {return Opc==PreInc || Opc==PostInc; } bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; } - bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; } bool isOffsetOfOp() const { return Opc == OffsetOf; } static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; } @@ -515,23 +513,39 @@ public: static UnaryOperator* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; -/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of -/// *types*. sizeof(expr) is handled by UnaryOperator. -class SizeOfAlignOfTypeExpr : public Expr { - bool isSizeof; // true if sizeof, false if alignof. - QualType Ty; +/// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of +/// types and expressions. +class SizeOfAlignOfExpr : public Expr { + bool isSizeof : 1; // true if sizeof, false if alignof. + bool isType : 1; // true if operand is a type, false if an expression + void *Argument; SourceLocation OpLoc, RParenLoc; public: - SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType, - SourceLocation op, SourceLocation rp) : - Expr(SizeOfAlignOfTypeExprClass, resultType), - isSizeof(issizeof), Ty(argType), OpLoc(op), RParenLoc(rp) {} - + SizeOfAlignOfExpr(bool issizeof, bool istype, void *argument, + QualType resultType, SourceLocation op, + SourceLocation rp) : + Expr(SizeOfAlignOfExprClass, resultType), + isSizeof(issizeof), isType(istype), Argument(argument), + OpLoc(op), RParenLoc(rp) {} + virtual void Destroy(ASTContext& C); bool isSizeOf() const { return isSizeof; } - QualType getArgumentType() const { return Ty; } - + bool isArgumentType() const { return isType; } + QualType getArgumentType() const { + assert(isArgumentType() && "calling getArgumentType() when arg is expr"); + return QualType::getFromOpaquePtr(Argument); + } + Expr* getArgumentExpr() const { + assert(!isArgumentType() && "calling getArgumentExpr() when arg is type"); + return (Expr *)Argument; + } + /// Gets the argument type, or the type of the argument expression, whichever + /// is appropriate. + QualType getTypeOfArgument() const { + return isArgumentType() ? getArgumentType() : getArgumentExpr()->getType(); + } + SourceLocation getOperatorLoc() const { return OpLoc; } virtual SourceRange getSourceRange() const { @@ -539,16 +553,16 @@ public: } static bool classof(const Stmt *T) { - return T->getStmtClass() == SizeOfAlignOfTypeExprClass; + return T->getStmtClass() == SizeOfAlignOfExprClass; } - static bool classof(const SizeOfAlignOfTypeExpr *) { return true; } + static bool classof(const SizeOfAlignOfExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); virtual void EmitImpl(llvm::Serializer& S) const; - static SizeOfAlignOfTypeExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); + static SizeOfAlignOfExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def index 2b814a0e4b0f..6a1c4248e4e4 100644 --- a/clang/include/clang/AST/StmtNodes.def +++ b/clang/include/clang/AST/StmtNodes.def @@ -67,7 +67,7 @@ STMT(37, StringLiteral , Expr) STMT(38, CharacterLiteral , Expr) STMT(39, ParenExpr , Expr) STMT(40, UnaryOperator , Expr) -STMT(41, SizeOfAlignOfTypeExpr , Expr) +STMT(41, SizeOfAlignOfExpr , Expr) STMT(42, ArraySubscriptExpr , Expr) STMT(43, CallExpr , Expr) STMT(44, MemberExpr , Expr) diff --git a/clang/include/clang/AST/StmtVisitor.h b/clang/include/clang/AST/StmtVisitor.h index fb1e4d120272..22b467ea73ce 100644 --- a/clang/include/clang/AST/StmtVisitor.h +++ b/clang/include/clang/AST/StmtVisitor.h @@ -91,8 +91,6 @@ public: case UnaryOperator::Minus: DISPATCH(UnaryMinus, UnaryOperator); case UnaryOperator::Not: DISPATCH(UnaryNot, UnaryOperator); case UnaryOperator::LNot: DISPATCH(UnaryLNot, UnaryOperator); - case UnaryOperator::SizeOf: DISPATCH(UnarySizeOf, UnaryOperator); - case UnaryOperator::AlignOf: DISPATCH(UnaryAlignOf, UnaryOperator); case UnaryOperator::Real: DISPATCH(UnaryReal, UnaryOperator); case UnaryOperator::Imag: DISPATCH(UnaryImag, UnaryOperator); case UnaryOperator::Extension: DISPATCH(UnaryExtension, UnaryOperator); @@ -158,7 +156,6 @@ public: UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus) UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot) - UNARYOP_FALLBACK(SizeOf) UNARYOP_FALLBACK(AlignOf) UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag) UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(OffsetOf) #undef UNARYOP_FALLBACK diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index 5339f6f3a26f..45874bb6819e 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -552,9 +552,9 @@ protected: /// VisitReturnStmt - Transfer function logic for return statements. void VisitReturnStmt(ReturnStmt* R, NodeTy* Pred, NodeSet& Dst); - /// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type). - void VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex, NodeTy* Pred, - NodeSet& Dst); + /// VisitSizeOfAlignOfExpr - Transfer function for sizeof. + void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, NodeTy* Pred, + NodeSet& Dst); /// VisitUnaryOperator - Transfer function logic for unary operators. void VisitUnaryOperator(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst, diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index d1ab26f69374..1e036e755984 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -520,9 +520,8 @@ public: return 0; } virtual ExprResult - ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof, - SourceLocation LParenLoc, TypeTy *Ty, - SourceLocation RParenLoc) { + ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, + void *TyOrEx, const SourceRange &ArgRange) { return 0; } diff --git a/clang/lib/AST/CFG.cpp b/clang/lib/AST/CFG.cpp index b75ec68e1584..95e188269e14 100644 --- a/clang/lib/AST/CFG.cpp +++ b/clang/lib/AST/CFG.cpp @@ -404,31 +404,23 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) { case Stmt::StmtExprClass: return WalkAST_VisitStmtExpr(cast(Terminator)); - case Stmt::SizeOfAlignOfTypeExprClass: { - SizeOfAlignOfTypeExpr* E = cast(Terminator); + case Stmt::SizeOfAlignOfExprClass: { + SizeOfAlignOfExpr* E = cast(Terminator); // VLA types have expressions that must be evaluated. - for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr()); - VA != 0; VA = FindVA(VA->getElementType().getTypePtr())) - addStmt(VA->getSizeExpr()); + if (E->isArgumentType()) { + for (VariableArrayType* VA = FindVA(E->getArgumentType().getTypePtr()); + VA != 0; VA = FindVA(VA->getElementType().getTypePtr())) + addStmt(VA->getSizeExpr()); + } + // Expressions in sizeof/alignof are not evaluated and thus have no + // control flow. + else + Block->appendStmt(Terminator); return Block; } - case Stmt::UnaryOperatorClass: { - UnaryOperator* U = cast(Terminator); - - // sizeof(expressions). For such expressions, - // the subexpression is not really evaluated, so - // we don't care about control-flow within the sizeof. - if (U->getOpcode() == UnaryOperator::SizeOf) { - Block->appendStmt(Terminator); - return Block; - } - - break; - } - case Stmt::BinaryOperatorClass: { BinaryOperator* B = cast(Terminator); diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 86a2f2902e95..fbb225613fd2 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -92,8 +92,6 @@ const char *UnaryOperator::getOpcodeStr(Opcode Op) { case LNot: return "!"; case Real: return "__real"; case Imag: return "__imag"; - case SizeOf: return "sizeof"; - case AlignOf: return "alignof"; case Extension: return "__extension__"; case OffsetOf: return "__builtin_offsetof"; } @@ -608,8 +606,7 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { // Get the operand value. If this is sizeof/alignof, do not evalute the // operand. This affects C99 6.6p3. - if (!Exp->isSizeOfAlignOfOp() && - Exp->getOpcode() != UnaryOperator::OffsetOf && + if (Exp->getOpcode() != UnaryOperator::OffsetOf && !Exp->getSubExpr()->isConstantExpr(Ctx, Loc)) return false; @@ -621,10 +618,7 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { return false; case UnaryOperator::Extension: return true; // FIXME: this is wrong. - case UnaryOperator::SizeOf: - case UnaryOperator::AlignOf: case UnaryOperator::OffsetOf: - // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. if (!Exp->getSubExpr()->getType()->isConstantSizeType()) { if (Loc) *Loc = Exp->getOperatorLoc(); return false; @@ -637,13 +631,15 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { return true; } } - case SizeOfAlignOfTypeExprClass: { - const SizeOfAlignOfTypeExpr *Exp = cast(this); + case SizeOfAlignOfExprClass: { + const SizeOfAlignOfExpr *Exp = cast(this); // alignof always evaluates to a constant. - if (Exp->isSizeOf() && !Exp->getArgumentType()->isVoidType() && - !Exp->getArgumentType()->isConstantSizeType()) { - if (Loc) *Loc = Exp->getOperatorLoc(); - return false; + if (Exp->isSizeOf()) { + QualType ArgTy = Exp->getTypeOfArgument(); + if (!ArgTy->isVoidType() && !ArgTy->isConstantSizeType()) { + if (Loc) *Loc = Exp->getOperatorLoc(); + return false; + } } return true; } @@ -784,10 +780,10 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, case UnaryOperatorClass: { const UnaryOperator *Exp = cast(this); - // Get the operand value. If this is sizeof/alignof, do not evalute the + // Get the operand value. If this is offsetof, do not evalute the // operand. This affects C99 6.6p3. - if (!Exp->isSizeOfAlignOfOp() && !Exp->isOffsetOfOp() && - !Exp->getSubExpr()->isIntegerConstantExpr(Result, Ctx, Loc,isEvaluated)) + if (!Exp->isOffsetOfOp() && !Exp->getSubExpr()-> + isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated)) return false; switch (Exp->getOpcode()) { @@ -798,35 +794,6 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, return false; case UnaryOperator::Extension: return true; // FIXME: this is wrong. - case UnaryOperator::SizeOf: - case UnaryOperator::AlignOf: - // Return the result in the right width. - Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); - - // sizeof(void) and __alignof__(void) = 1 as a gcc extension. - if (Exp->getSubExpr()->getType()->isVoidType()) { - Result = 1; - break; - } - - // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. - if (!Exp->getSubExpr()->getType()->isConstantSizeType()) { - if (Loc) *Loc = Exp->getOperatorLoc(); - return false; - } - - // Get information about the size or align. - if (Exp->getSubExpr()->getType()->isFunctionType()) { - // GCC extension: sizeof(function) = 1. - Result = Exp->getOpcode() == UnaryOperator::AlignOf ? 4 : 1; - } else { - unsigned CharSize = Ctx.Target.getCharWidth(); - if (Exp->getOpcode() == UnaryOperator::AlignOf) - Result = Ctx.getTypeAlign(Exp->getSubExpr()->getType()) / CharSize; - else - Result = Ctx.getTypeSize(Exp->getSubExpr()->getType()) / CharSize; - } - break; case UnaryOperator::LNot: { bool Val = Result == 0; Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); @@ -847,34 +814,35 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, } break; } - case SizeOfAlignOfTypeExprClass: { - const SizeOfAlignOfTypeExpr *Exp = cast(this); + case SizeOfAlignOfExprClass: { + const SizeOfAlignOfExpr *Exp = cast(this); // Return the result in the right width. Result.zextOrTrunc(static_cast(Ctx.getTypeSize(getType()))); + QualType ArgTy = Exp->getTypeOfArgument(); // sizeof(void) and __alignof__(void) = 1 as a gcc extension. - if (Exp->getArgumentType()->isVoidType()) { + if (ArgTy->isVoidType()) { Result = 1; break; } // alignof always evaluates to a constant, sizeof does if arg is not VLA. - if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) { + if (Exp->isSizeOf() && !ArgTy->isConstantSizeType()) { if (Loc) *Loc = Exp->getOperatorLoc(); return false; } // Get information about the size or align. - if (Exp->getArgumentType()->isFunctionType()) { + if (ArgTy->isFunctionType()) { // GCC extension: sizeof(function) = 1. Result = Exp->isSizeOf() ? 1 : 4; } else { unsigned CharSize = Ctx.Target.getCharWidth(); if (Exp->isSizeOf()) - Result = Ctx.getTypeSize(Exp->getArgumentType()) / CharSize; + Result = Ctx.getTypeSize(ArgTy) / CharSize; else - Result = Ctx.getTypeAlign(Exp->getArgumentType()) / CharSize; + Result = Ctx.getTypeAlign(ArgTy) / CharSize; } break; } @@ -1280,9 +1248,18 @@ int64_t UnaryOperator::evaluateOffsetOf(ASTContext& C) const return ::evaluateOffsetOf(C, cast(Val)) / CharSize; } -void SizeOfAlignOfTypeExpr::Destroy(ASTContext& C) { - // Override default behavior of traversing children. We do not want - // to delete the type. +void SizeOfAlignOfExpr::Destroy(ASTContext& C) { + // Override default behavior of traversing children. If this has a type + // operand and the type is a variable-length array, the child iteration + // will iterate over the size expression. However, this expression belongs + // to the type, not to this, so we don't want to delete it. + // We still want to delete this expression. + // FIXME: Same as in Stmt::Destroy - will be eventually in ASTContext's + // pool allocator. + if (isArgumentType()) + delete this; + else + Expr::Destroy(C); } //===----------------------------------------------------------------------===// @@ -1350,17 +1327,23 @@ Stmt::child_iterator ParenExpr::child_end() { return &Val+1; } Stmt::child_iterator UnaryOperator::child_begin() { return &Val; } Stmt::child_iterator UnaryOperator::child_end() { return &Val+1; } -// SizeOfAlignOfTypeExpr -Stmt::child_iterator SizeOfAlignOfTypeExpr::child_begin() { - // If the type is a VLA type (and not a typedef), the size expression of the - // VLA needs to be treated as an executable expression. - if (VariableArrayType* T = dyn_cast(Ty.getTypePtr())) - return child_iterator(T); - else - return child_iterator(); +// SizeOfAlignOfExpr +Stmt::child_iterator SizeOfAlignOfExpr::child_begin() { + // If this is of a type and the type is a VLA type (and not a typedef), the + // size expression of the VLA needs to be treated as an executable expression. + // Why isn't this weirdness documented better in StmtIterator? + if (isArgumentType()) { + if (VariableArrayType* T = dyn_cast( + getArgumentType().getTypePtr())) + return child_iterator(T); + return child_iterator(); + } + return child_iterator((Stmt**)&Argument); } -Stmt::child_iterator SizeOfAlignOfTypeExpr::child_end() { - return child_iterator(); +Stmt::child_iterator SizeOfAlignOfExpr::child_end() { + if (isArgumentType()) + return child_iterator(); + return child_iterator((Stmt**)&Argument + 1); } // ArraySubscriptExpr diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 12010646bced..99fa8d5813dd 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -222,14 +222,10 @@ public: bool VisitCastExpr(CastExpr* E) { return HandleCast(E->getLocStart(), E->getSubExpr(), E->getType()); } - bool VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) { - return EvaluateSizeAlignOf(E->isSizeOf(), E->getArgumentType(), - E->getType()); - } - + bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E); + private: bool HandleCast(SourceLocation CastLoc, Expr *SubExpr, QualType DestType); - bool EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, QualType DstTy); }; } // end anonymous namespace @@ -426,14 +422,16 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return true; } -/// EvaluateSizeAlignOf - Evaluate sizeof(SrcTy) or alignof(SrcTy) with a result -/// as a DstTy type. -bool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, - QualType DstTy) { +/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the +/// expression's type. +bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { + QualType DstTy = E->getType(); // Return the result in the right width. Result.zextOrTrunc(getIntTypeSizeInBits(DstTy)); Result.setIsUnsigned(DstTy->isUnsignedIntegerType()); + QualType SrcTy = E->getTypeOfArgument(); + // sizeof(void) and __alignof__(void) = 1 as a gcc extension. if (SrcTy->isVoidType()) Result = 1; @@ -443,6 +441,8 @@ bool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, // FIXME: Should we attempt to evaluate this? return false; } + + bool isSizeOf = E->isSizeOf(); // GCC extension: sizeof(function) = 1. if (SrcTy->isFunctionType()) { @@ -470,10 +470,6 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { return true; } - if (E->isSizeOfAlignOfOp()) - return EvaluateSizeAlignOf(E->getOpcode() == UnaryOperator::SizeOf, - E->getSubExpr()->getType(), E->getType()); - // Get the operand value into 'Result'. if (!Visit(E->getSubExpr())) return false; diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index ecfdbf78d27f..0b9e62d2c568 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -119,7 +119,7 @@ namespace { void VisitFloatingLiteral(FloatingLiteral *Node); void VisitStringLiteral(StringLiteral *Str); void VisitUnaryOperator(UnaryOperator *Node); - void VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node); + void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node); void VisitMemberExpr(MemberExpr *Node); void VisitExtVectorElementExpr(ExtVectorElementExpr *Node); void VisitBinaryOperator(BinaryOperator *Node); @@ -363,10 +363,11 @@ void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) { fprintf(F, " %s '%s'", Node->isPostfix() ? "postfix" : "prefix", UnaryOperator::getOpcodeStr(Node->getOpcode())); } -void StmtDumper::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) { +void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { DumpExpr(Node); fprintf(F, " %s ", Node->isSizeOf() ? "sizeof" : "alignof"); - DumpType(Node->getArgumentType()); + if (Node->isArgumentType()) + DumpType(Node->getArgumentType()); } void StmtDumper::VisitMemberExpr(MemberExpr *Node) { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index cc861cc6b4e4..7529eec98478 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -620,11 +620,9 @@ void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { if (!Node->isPostfix()) { OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); - // Print a space if this is an "identifier operator" like sizeof or __real. + // Print a space if this is an "identifier operator" like __real. switch (Node->getOpcode()) { default: break; - case UnaryOperator::SizeOf: - case UnaryOperator::AlignOf: case UnaryOperator::Real: case UnaryOperator::Imag: case UnaryOperator::Extension: @@ -663,9 +661,14 @@ void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { OS << ")"; } -void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) { - OS << (Node->isSizeOf() ? "sizeof(" : "__alignof("); - OS << Node->getArgumentType().getAsString() << ")"; +void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { + OS << (Node->isSizeOf() ? "sizeof" : "__alignof"); + if (Node->isArgumentType()) + OS << "(" << Node->getArgumentType().getAsString() << ")"; + else { + OS << " "; + PrintExpr(Node->getArgumentExpr()); + } } void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { PrintExpr(Node->getLHS()); diff --git a/clang/lib/AST/StmtSerialization.cpp b/clang/lib/AST/StmtSerialization.cpp index 398288157691..f71b88b46f1d 100644 --- a/clang/lib/AST/StmtSerialization.cpp +++ b/clang/lib/AST/StmtSerialization.cpp @@ -136,8 +136,8 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) { case ReturnStmtClass: return ReturnStmt::CreateImpl(D, C); - case SizeOfAlignOfTypeExprClass: - return SizeOfAlignOfTypeExpr::CreateImpl(D, C); + case SizeOfAlignOfExprClass: + return SizeOfAlignOfExpr::CreateImpl(D, C); case StmtExprClass: return StmtExpr::CreateImpl(D, C); @@ -795,22 +795,33 @@ ReturnStmt* ReturnStmt::CreateImpl(Deserializer& D, ASTContext& C) { return new ReturnStmt(RetLoc,RetExpr); } -void SizeOfAlignOfTypeExpr::EmitImpl(Serializer& S) const { +void SizeOfAlignOfExpr::EmitImpl(Serializer& S) const { S.EmitBool(isSizeof); - S.Emit(Ty); + S.EmitBool(isType); + if (isType) + S.Emit(getArgumentType()); + else + S.EmitOwnedPtr(getArgumentExpr()); S.Emit(getType()); S.Emit(OpLoc); S.Emit(RParenLoc); } -SizeOfAlignOfTypeExpr* SizeOfAlignOfTypeExpr::CreateImpl(Deserializer& D, ASTContext& C) { +SizeOfAlignOfExpr* +SizeOfAlignOfExpr::CreateImpl(Deserializer& D, ASTContext& C) { bool isSizeof = D.ReadBool(); - QualType Ty = QualType::ReadVal(D); + bool isType = D.ReadBool(); + void *Argument; + if (isType) + Argument = QualType::ReadVal(D).getAsOpaquePtr(); + else + Argument = D.ReadOwnedPtr(C); QualType Res = QualType::ReadVal(D); SourceLocation OpLoc = SourceLocation::ReadVal(D); SourceLocation RParenLoc = SourceLocation::ReadVal(D); - return new SizeOfAlignOfTypeExpr(isSizeof,Ty,Res,OpLoc,RParenLoc); + return new SizeOfAlignOfExpr(isSizeof, isType, Argument, Res, + OpLoc, RParenLoc); } void StmtExpr::EmitImpl(Serializer& S) const { diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index 11ce8ea7ff98..8e6d5ab5cc35 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -380,8 +380,8 @@ void GRExprEngine::Visit(Stmt* S, NodeTy* Pred, NodeSet& Dst) { VisitReturnStmt(cast(S), Pred, Dst); break; - case Stmt::SizeOfAlignOfTypeExprClass: - VisitSizeOfAlignOfTypeExpr(cast(S), Pred, Dst); + case Stmt::SizeOfAlignOfExprClass: + VisitSizeOfAlignOfExpr(cast(S), Pred, Dst); break; case Stmt::StmtExprClass: { @@ -1749,11 +1749,11 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred, assert(0 && "unprocessed InitListExpr type"); } -/// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type). -void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex, - NodeTy* Pred, - NodeSet& Dst) { - QualType T = Ex->getArgumentType(); +/// VisitSizeOfAlignOfExpr - Transfer function for sizeof(type). +void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, + NodeTy* Pred, + NodeSet& Dst) { + QualType T = Ex->getTypeOfArgument(); uint64_t amt; if (Ex->isSizeOf()) { @@ -1972,40 +1972,6 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, return; } - - case UnaryOperator::AlignOf: { - - QualType T = U->getSubExpr()->getType(); - - // FIXME: Add support for VLAs. - - if (!T.getTypePtr()->isConstantSizeType()) - return; - - uint64_t size = getContext().getTypeAlign(T) / 8; - const GRState* St = GetState(Pred); - St = BindExpr(St, U, NonLoc::MakeVal(getBasicVals(), size, U->getType())); - - MakeNode(Dst, U, Pred, St); - return; - } - - case UnaryOperator::SizeOf: { - - QualType T = U->getSubExpr()->getType(); - - // FIXME: Add support for VLAs. - - if (!T.getTypePtr()->isConstantSizeType()) - return; - - uint64_t size = getContext().getTypeSize(T) / 8; - const GRState* St = GetState(Pred); - St = BindExpr(St, U, NonLoc::MakeVal(getBasicVals(), size, U->getType())); - - MakeNode(Dst, U, Pred, St); - return; - } } // Handle ++ and -- (both pre- and post-increment). diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index 9b0f09e54e36..07fda99166c4 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -195,7 +195,6 @@ void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) { Expr *E = U->getSubExpr(); switch (U->getOpcode()) { - case UnaryOperator::SizeOf: return; case UnaryOperator::PostInc: case UnaryOperator::PostDec: case UnaryOperator::PreInc: diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index a02e544506e1..60489023b26e 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -171,9 +171,6 @@ bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) { break; } - case UnaryOperator::SizeOf: - return Initialized; - default: break; } diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 92226620269a..b4ca6c0f57fc 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -117,7 +117,7 @@ public: } ComplexPairTy VisitUnaryMinus (const UnaryOperator *E); ComplexPairTy VisitUnaryNot (const UnaryOperator *E); - // LNot,SizeOf,AlignOf,Real,Imag never return complex. + // LNot,Real,Imag never return complex. ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { return Visit(E->getSubExpr()); } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 89b34e611ba8..1e224571f952 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -384,8 +384,8 @@ public: return 0; } - llvm::Constant *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) { - return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf()); + llvm::Constant *VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { + return EmitSizeAlignOf(E->getTypeOfArgument(), E->getType(), E->isSizeOf()); } llvm::Constant *VisitAddrLabelExpr(const AddrLabelExpr *E) { @@ -426,12 +426,6 @@ public: return llvm::ConstantExpr::getZExt(SubExpr, ConvertType(E->getType())); } - llvm::Constant *VisitUnarySizeOf(const UnaryOperator *E) { - return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true); - } - llvm::Constant *VisitUnaryAlignOf(const UnaryOperator *E) { - return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false); - } llvm::Constant *VisitUnaryAddrOf(const UnaryOperator *E) { return EmitLValue(E->getSubExpr()); } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 465574187aa9..82f0cc7e7773 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -117,9 +117,7 @@ public: CGF.getContext().typesAreCompatible( E->getArgType1(), E->getArgType2())); } - Value *VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) { - return EmitSizeAlignOf(E->getArgumentType(), E->getType(), E->isSizeOf()); - } + Value *VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E); Value *VisitAddrLabelExpr(const AddrLabelExpr *E) { llvm::Value *V = llvm::ConstantInt::get(llvm::Type::Int32Ty, @@ -235,14 +233,6 @@ public: Value *VisitUnaryMinus (const UnaryOperator *E); Value *VisitUnaryNot (const UnaryOperator *E); Value *VisitUnaryLNot (const UnaryOperator *E); - Value *VisitUnarySizeOf (const UnaryOperator *E) { - return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true); - } - Value *VisitUnaryAlignOf (const UnaryOperator *E) { - return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false); - } - Value *EmitSizeAlignOf(QualType TypeToSize, QualType RetType, - bool isSizeOf); Value *VisitUnaryReal (const UnaryOperator *E); Value *VisitUnaryImag (const UnaryOperator *E); Value *VisitUnaryExtension(const UnaryOperator *E) { @@ -653,14 +643,16 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { return Builder.CreateZExt(BoolVal, CGF.LLVMIntTy, "lnot.ext"); } -/// EmitSizeAlignOf - Return the size or alignment of the 'TypeToSize' type as -/// an integer (RetType). -Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize, - QualType RetType,bool isSizeOf){ +/// VisitSizeOfAlignOfExpr - Return the size or alignment of the type of +/// argument of the sizeof expression as an integer. +Value * +ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { + QualType RetType = E->getType(); assert(RetType->isIntegerType() && "Result type must be an integer!"); uint32_t ResultWidth = static_cast(CGF.getContext().getTypeSize(RetType)); + QualType TypeToSize = E->getTypeOfArgument(); // sizeof(void) and __alignof__(void) = 1 as a gcc extension. Also // for function types. // FIXME: what is alignof a function type in gcc? @@ -670,7 +662,7 @@ Value *ScalarExprEmitter::EmitSizeAlignOf(QualType TypeToSize, /// FIXME: This doesn't handle VLAs yet! std::pair Info = CGF.getContext().getTypeInfo(TypeToSize); - uint64_t Val = isSizeOf ? Info.first : Info.second; + uint64_t Val = E->isSizeOf() ? Info.first : Info.second; Val /= 8; // Return size in bytes, not bits. return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index df55bf79fcae..467eef03b6f3 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -764,9 +764,10 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() { // If ParseParenExpression parsed a '(typename)' sequence only, the this is // sizeof/alignof a type. Otherwise, it is sizeof/alignof an expression. if (ExprType == CastExpr) - return Actions.ActOnSizeOfAlignOfTypeExpr(OpTok.getLocation(), - OpTok.is(tok::kw_sizeof), - LParenLoc, CastTy, RParenLoc); + return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(), + OpTok.is(tok::kw_sizeof), + /*isType=*/true, CastTy, + SourceRange(LParenLoc, RParenLoc)); // If this is a parenthesized expression, it is the start of a // unary-expression, but doesn't include any postfix pieces. Parse these @@ -776,8 +777,10 @@ Parser::ExprResult Parser::ParseSizeofAlignofExpression() { // If we get here, the operand to the sizeof/alignof was an expresion. if (!Operand.isInvalid) - Operand = Actions.ActOnUnaryOp(OpTok.getLocation(), OpTok.getKind(), - Operand.Val); + Operand = Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(), + OpTok.is(tok::kw_sizeof), + /*isType=*/false, Operand.Val, + SourceRange()); return Operand; } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 7f72928064a1..7cd507a0aa30 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -624,9 +624,11 @@ public: virtual ExprResult ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Op, ExprTy *Input); virtual ExprResult - ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof, - SourceLocation LParenLoc, TypeTy *Ty, - SourceLocation RParenLoc); + ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, + void *TyOrEx, const SourceRange &ArgRange); + + bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc, + const SourceRange &R, bool isSizeof); virtual ExprResult ActOnPostfixUnaryOp(SourceLocation OpLoc, tok::TokenKind Kind, ExprTy *Input); @@ -1208,8 +1210,6 @@ public: QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc); QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc); QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc); - QualType CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc, - const SourceRange &R, bool isSizeof); QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc); /// type checking primary expressions. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b595ad7f317a..fc412a605edf 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1470,11 +1470,7 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { default: InitializerElementNotConstant(Init); return true; - case UnaryOperator::SizeOf: - case UnaryOperator::AlignOf: case UnaryOperator::OffsetOf: - // sizeof(E) is a constantexpr if and only if E is not evaluted. - // See C99 6.5.3.4p2 and 6.6p3. if (Exp->getSubExpr()->getType()->isConstantSizeType()) return false; InitializerElementNotConstant(Init); @@ -1487,14 +1483,14 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { return CheckArithmeticConstantExpression(Exp->getSubExpr()); } } - case Expr::SizeOfAlignOfTypeExprClass: { - const SizeOfAlignOfTypeExpr *Exp = cast(Init); + case Expr::SizeOfAlignOfExprClass: { + const SizeOfAlignOfExpr *Exp = cast(Init); // Special check for void types, which are allowed as an extension - if (Exp->getArgumentType()->isVoidType()) + if (Exp->getTypeOfArgument()->isVoidType()) return false; // alignof always evaluates to a constant. // FIXME: is sizeof(int[3.0]) a constant expression? - if (Exp->isSizeOf() && !Exp->getArgumentType()->isConstantSizeType()) { + if (Exp->isSizeOf() && !Exp->getTypeOfArgument()->isConstantSizeType()) { InitializerElementNotConstant(Init); return true; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a45d6717b797..92efa68cc434 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -654,10 +654,10 @@ Action::ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, /// The UsualUnaryConversions() function is *not* called by this routine. /// See C99 6.3.2.1p[2-4] for more details. -QualType Sema::CheckSizeOfAlignOfOperand(QualType exprType, - SourceLocation OpLoc, - const SourceRange &ExprRange, - bool isSizeof) { +bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, + SourceLocation OpLoc, + const SourceRange &ExprRange, + bool isSizeof) { // C99 6.5.3.4p1: if (isa(exprType) && isSizeof) // alignof(function) is allowed. @@ -669,28 +669,40 @@ QualType Sema::CheckSizeOfAlignOfOperand(QualType exprType, Diag(OpLoc, isSizeof ? diag::err_sizeof_incomplete_type : diag::err_alignof_incomplete_type, exprType.getAsString(), ExprRange); - return QualType(); // error + return true; // error } - // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. - return Context.getSizeType(); + + return false; } -Action::ExprResult Sema:: -ActOnSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof, - SourceLocation LPLoc, TypeTy *Ty, - SourceLocation RPLoc) { +/// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and +/// the same for @c alignof and @c __alignof +/// Note that the ArgRange is invalid if isType is false. +Action::ExprResult +Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, + void *TyOrEx, const SourceRange &ArgRange) { // If error parsing type, ignore. - if (Ty == 0) return true; - - // Verify that this is a valid expression. - QualType ArgTy = QualType::getFromOpaquePtr(Ty); - - QualType resultType = - CheckSizeOfAlignOfOperand(ArgTy, OpLoc, SourceRange(LPLoc, RPLoc),isSizeof); + if (TyOrEx == 0) return true; - if (resultType.isNull()) + QualType ArgTy; + SourceRange Range; + if (isType) { + ArgTy = QualType::getFromOpaquePtr(TyOrEx); + Range = ArgRange; + } else { + // Get the end location. + Expr *ArgEx = (Expr *)TyOrEx; + Range = ArgEx->getSourceRange(); + ArgTy = ArgEx->getType(); + } + + // Verify that the operand is valid. + if (CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, isSizeof)) return true; - return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, resultType, OpLoc, RPLoc); + + // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. + return new SizeOfAlignOfExpr(isSizeof, isType, TyOrEx, Context.getSizeType(), + OpLoc, Range.getEnd()); } QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc) { @@ -2635,8 +2647,6 @@ static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode( case tok::minus: Opc = UnaryOperator::Minus; break; case tok::tilde: Opc = UnaryOperator::Not; break; case tok::exclaim: Opc = UnaryOperator::LNot; break; - case tok::kw_sizeof: Opc = UnaryOperator::SizeOf; break; - case tok::kw___alignof: Opc = UnaryOperator::AlignOf; break; case tok::kw___real: Opc = UnaryOperator::Real; break; case tok::kw___imag: Opc = UnaryOperator::Imag; break; case tok::kw___extension__: Opc = UnaryOperator::Extension; break; @@ -2902,14 +2912,6 @@ Action::ExprResult Sema::ActOnUnaryOp(SourceLocation OpLoc, tok::TokenKind Op, // LNot always has type int. C99 6.5.3.3p5. resultType = Context.IntTy; break; - case UnaryOperator::SizeOf: - resultType = CheckSizeOfAlignOfOperand(Input->getType(), OpLoc, - Input->getSourceRange(), true); - break; - case UnaryOperator::AlignOf: - resultType = CheckSizeOfAlignOfOperand(Input->getType(), OpLoc, - Input->getSourceRange(), false); - break; case UnaryOperator::Real: case UnaryOperator::Imag: resultType = CheckRealImagOperand(Input, OpLoc);