]> granicus.if.org Git - clang/commitdiff
implement codegen support for sizeof/alignof
authorChris Lattner <sabre@nondot.org>
Wed, 18 Jul 2007 18:12:07 +0000 (18:12 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 18 Jul 2007 18:12:07 +0000 (18:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40009 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGExpr.cpp
CodeGen/CodeGenFunction.h

index 40c25ae0bbda7447273704ffb4a9e4c46811b6db..dd137634711606e6c3cbca5d6fce7445734d5160 100644 (file)
@@ -473,6 +473,10 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) {
     return EmitExpr(cast<ParenExpr>(E)->getSubExpr());
   case Expr::UnaryOperatorClass:
     return EmitUnaryOperator(cast<UnaryOperator>(E));
+  case Expr::SizeOfAlignOfTypeExprClass:
+    return EmitSizeAlignOf(cast<SizeOfAlignOfTypeExpr>(E)->getArgumentType(),
+                           E->getType(),
+                           cast<SizeOfAlignOfTypeExpr>(E)->isSizeOf());
   case Expr::ImplicitCastExprClass:
     return EmitCastExpr(cast<ImplicitCastExpr>(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<uint64_t, unsigned> 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
index 67cefc2714b9308cfb825a2bb3a44d2dac989c61..db92ee29b9acc6a42e9a9afb2e963a74eb3cac5c 100644 (file)
@@ -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.