From: Chris Lattner Date: Wed, 18 Jul 2007 18:12:07 +0000 (+0000) Subject: implement codegen support for sizeof/alignof X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5e3fbe503a28c790d648091653dc21eeca64ca07;p=clang implement codegen support for sizeof/alignof git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40009 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index 40c25ae0bb..dd13763471 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -473,6 +473,10 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) { return EmitExpr(cast(E)->getSubExpr()); case Expr::UnaryOperatorClass: return EmitUnaryOperator(cast(E)); + case Expr::SizeOfAlignOfTypeExprClass: + return EmitSizeAlignOf(cast(E)->getArgumentType(), + E->getType(), + cast(E)->isSizeOf()); case Expr::ImplicitCastExprClass: return EmitCastExpr(cast(E)->getSubExpr(), E->getType()); case Expr::CastExprClass: @@ -655,7 +659,10 @@ RValue CodeGenFunction::EmitUnaryOperator(const UnaryOperator *E) { case UnaryOperator::Minus : return EmitUnaryMinus(E); case UnaryOperator::Not : return EmitUnaryNot(E); case UnaryOperator::LNot : return EmitUnaryLNot(E); - // FIXME: SIZEOF/ALIGNOF(expr). + case UnaryOperator::SizeOf : + return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), true); + case UnaryOperator::AlignOf : + return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false); // FIXME: real/imag case UnaryOperator::Extension: return EmitExpr(E->getSubExpr()); } @@ -751,6 +758,23 @@ RValue CodeGenFunction::EmitUnaryLNot(const UnaryOperator *E) { return RValue::get(Builder.CreateZExt(BoolVal, LLVMIntTy, "lnot.ext")); } +/// EmitSizeAlignOf - Return the size or alignment of the 'TypeToSize' type as +/// an integer (RetType). +RValue CodeGenFunction::EmitSizeAlignOf(QualType TypeToSize, + QualType RetType, bool isSizeOf) { + /// FIXME: This doesn't handle VLAs yet! + std::pair Info = + getContext().getTypeInfo(TypeToSize, SourceLocation()); + + uint64_t Val = isSizeOf ? Info.first : Info.second; + Val /= 8; // Return size in bytes, not bits. + + assert(RetType->isIntegerType() && "Result type must be an integer!"); + + unsigned ResultWidth = getContext().getTypeSize(RetType, SourceLocation()); + return RValue::get(llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val))); +} + //===--------------------------------------------------------------------===// // Binary Operator Emission diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h index 67cefc2714..db92ee29b9 100644 --- a/CodeGen/CodeGenFunction.h +++ b/CodeGen/CodeGenFunction.h @@ -340,7 +340,7 @@ public: RValue EmitUnaryMinus (const UnaryOperator *E); RValue EmitUnaryNot (const UnaryOperator *E); RValue EmitUnaryLNot (const UnaryOperator *E); - // FIXME: SIZEOF/ALIGNOF(expr). + RValue EmitSizeAlignOf (QualType TypeToSize, QualType RetType,bool isSizeOf); // FIXME: real/imag // Binary Operators.