zcov: / lib/CodeGen/CGExprAgg.cpp


Files: 1 Branches Taken: 65.9% 91 / 138
Generated: 2010-02-10 01:31 Branches Executed: 87.0% 120 / 138
Line Coverage: 83.0% 273 / 329


Programs: 1 Runs 2897


       1                 : //===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : // This contains code to emit Aggregate Expr nodes as LLVM code.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "CodeGenFunction.h"
      15                 : #include "CodeGenModule.h"
      16                 : #include "CGObjCRuntime.h"
      17                 : #include "clang/AST/ASTContext.h"
      18                 : #include "clang/AST/DeclCXX.h"
      19                 : #include "clang/AST/StmtVisitor.h"
      20                 : #include "llvm/Constants.h"
      21                 : #include "llvm/Function.h"
      22                 : #include "llvm/GlobalVariable.h"
      23                 : #include "llvm/Intrinsics.h"
      24                 : using namespace clang;
      25                 : using namespace CodeGen;
      26                 : 
      27                 : //===----------------------------------------------------------------------===//
      28                 : //                        Aggregate Expression Emitter
      29                 : //===----------------------------------------------------------------------===//
      30                 : 
      31                 : namespace  {
      32                 : class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
      33                 :   CodeGenFunction &CGF;
      34                 :   CGBuilderTy &Builder;
      35                 :   llvm::Value *DestPtr;
      36                 :   bool VolatileDest;
      37                 :   bool IgnoreResult;
      38                 :   bool IsInitializer;
      39                 :   bool RequiresGCollection;
      40                 : public:
      41                 :   AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
      42             1110:                  bool ignore, bool isinit, bool requiresGCollection)
      43                 :     : CGF(cgf), Builder(CGF.Builder),
      44                 :       DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore),
      45             1110:       IsInitializer(isinit), RequiresGCollection(requiresGCollection) {
      46             1110:   }
      47                 : 
      48                 :   //===--------------------------------------------------------------------===//
      49                 :   //                               Utilities
      50                 :   //===--------------------------------------------------------------------===//
      51                 : 
      52                 :   /// EmitAggLoadOfLValue - Given an expression with aggregate type that
      53                 :   /// represents a value lvalue, this method emits the address of the lvalue,
      54                 :   /// then loads the result into DestPtr.
      55                 :   void EmitAggLoadOfLValue(const Expr *E);
      56                 : 
      57                 :   /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
      58                 :   void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
      59                 :   void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
      60                 : 
      61                 :   //===--------------------------------------------------------------------===//
      62                 :   //                            Visitor Methods
      63                 :   //===--------------------------------------------------------------------===//
      64                 : 
      65                0:   void VisitStmt(Stmt *S) {
      66                0:     CGF.ErrorUnsupported(S, "aggregate expression");
      67                0:   }
      68               10:   void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); }
      69                0:   void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); }
      70                 : 
      71                 :   // l-values.
      72               81:   void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
      73                8:   void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
      74                6:   void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
      75                5:   void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
      76               17:   void VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
      77               17:     EmitAggLoadOfLValue(E);
      78               17:   }
      79                2:   void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
      80                2:     EmitAggLoadOfLValue(E);
      81                2:   }
      82                1:   void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
      83                1:     EmitAggLoadOfLValue(E);
      84                1:   }
      85                1:   void VisitPredefinedExpr(const PredefinedExpr *E) {
      86                1:     EmitAggLoadOfLValue(E);
      87                1:   }
      88                 : 
      89                 :   // Operators.
      90                 :   void VisitCastExpr(CastExpr *E);
      91                 :   void VisitCallExpr(const CallExpr *E);
      92                 :   void VisitStmtExpr(const StmtExpr *E);
      93                 :   void VisitBinaryOperator(const BinaryOperator *BO);
      94                 :   void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
      95                 :   void VisitBinAssign(const BinaryOperator *E);
      96                 :   void VisitBinComma(const BinaryOperator *E);
      97                 :   void VisitUnaryAddrOf(const UnaryOperator *E);
      98                 : 
      99                 :   void VisitObjCMessageExpr(ObjCMessageExpr *E);
     100                2:   void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
     101                2:     EmitAggLoadOfLValue(E);
     102                2:   }
     103                 :   void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
     104                 :   void VisitObjCImplicitSetterGetterRefExpr(ObjCImplicitSetterGetterRefExpr *E);
     105                 : 
     106                 :   void VisitConditionalOperator(const ConditionalOperator *CO);
     107                 :   void VisitChooseExpr(const ChooseExpr *CE);
     108                 :   void VisitInitListExpr(InitListExpr *E);
     109                 :   void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
     110                7:   void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
     111                7:     Visit(DAE->getExpr());
     112                7:   }
     113                 :   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
     114                 :   void VisitCXXConstructExpr(const CXXConstructExpr *E);
     115                 :   void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
     116                 :   void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
     117               14:   void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); }
     118                 : 
     119                 :   void VisitVAArgExpr(VAArgExpr *E);
     120                 : 
     121                 :   void EmitInitializationToLValue(Expr *E, LValue Address, QualType T);
     122                 :   void EmitNullInitializationToLValue(LValue Address, QualType T);
     123                 :   //  case Expr::ChooseExprClass:
     124                0:   void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
     125                 : };
     126                 : }  // end anonymous namespace.
     127                 : 
     128                 : //===----------------------------------------------------------------------===//
     129                 : //                                Utilities
     130                 : //===----------------------------------------------------------------------===//
     131                 : 
     132                 : /// EmitAggLoadOfLValue - Given an expression with aggregate type that
     133                 : /// represents a value lvalue, this method emits the address of the lvalue,
     134                 : /// then loads the result into DestPtr.
     135              156: void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
     136              156:   LValue LV = CGF.EmitLValue(E);
     137              156:   EmitFinalDestCopy(E, LV);
     138              156: }
     139                 : 
     140                 : /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
     141              203: void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
                      203: branch 1 taken
                        0: branch 2 not taken
     142              203:   assert(Src.isAggregate() && "value must be aggregate value!");
     143                 : 
     144                 :   // If the result is ignored, don't copy from the value.
                       78: branch 0 taken
                      125: branch 1 taken
     145              203:   if (DestPtr == 0) {
                        9: branch 1 taken
                       69: branch 2 taken
                        8: branch 3 taken
                        1: branch 4 taken
                        5: branch 5 taken
                        3: branch 6 taken
                       74: branch 7 taken
                        4: branch 8 taken
     146               78:     if (!Src.isVolatileQualified() || (IgnoreResult && Ignore))
     147               74:       return;
     148                 :     // If the source is volatile, we must read from it; to do that, we need
     149                 :     // some place to put it.
     150                4:     DestPtr = CGF.CreateMemTemp(E->getType(), "agg.tmp");
     151                 :   }
     152                 : 
                        5: branch 0 taken
                      124: branch 1 taken
     153              129:   if (RequiresGCollection) {
     154                 :     CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
     155                 :                                               DestPtr, Src.getAggregateAddr(),
     156                5:                                               E->getType());
     157                5:     return;
     158                 :   }
     159                 :   // If the result of the assignment is used, copy the LHS there also.
     160                 :   // FIXME: Pass VolatileDest as well.  I think we also need to merge volatile
     161                 :   // from the source as well, as we can't eliminate it if either operand
     162                 :   // is volatile, unless copy has volatile for both source and destination..
     163                 :   CGF.EmitAggregateCopy(DestPtr, Src.getAggregateAddr(), E->getType(),
     164              124:                         VolatileDest|Src.isVolatileQualified());
     165                 : }
     166                 : 
     167                 : /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
     168              193: void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
                      193: branch 1 taken
                        0: branch 2 not taken
     169              193:   assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
     170                 : 
     171                 :   EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(),
     172                 :                                             Src.isVolatileQualified()),
     173              193:                     Ignore);
     174              193: }
     175                 : 
     176                 : //===----------------------------------------------------------------------===//
     177                 : //                            Visitor Methods
     178                 : //===----------------------------------------------------------------------===//
     179                 : 
     180              153: void AggExprEmitter::VisitCastExpr(CastExpr *E) {
                        0: branch 1 not taken
                        3: branch 2 taken
                      142: branch 3 taken
                        4: branch 4 taken
                        0: branch 5 not taken
                        4: branch 6 taken
     181              153:   switch (E->getCastKind()) {
     182                0:   default: assert(0 && "Unhandled cast kind!");
     183                 : 
     184                 :   case CastExpr::CK_ToUnion: {
     185                 :     // GCC union extension
     186                 :     QualType PtrTy =
     187                3:     CGF.getContext().getPointerType(E->getSubExpr()->getType());
     188                 :     llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
     189                3:                                                  CGF.ConvertType(PtrTy));
     190                 :     EmitInitializationToLValue(E->getSubExpr(),
     191                 :                                LValue::MakeAddr(CastPtr, Qualifiers()), 
     192                3:                                E->getType());
     193                3:     break;
     194                 :   }
     195                 : 
     196                 :   // FIXME: Remove the CK_Unknown check here.
     197                 :   case CastExpr::CK_Unknown:
     198                 :   case CastExpr::CK_NoOp:
     199                 :   case CastExpr::CK_UserDefinedConversion:
     200                 :   case CastExpr::CK_ConstructorConversion:
     201                 :     assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
     202                 :                                                    E->getType()) &&
                      142: branch 5 taken
                        0: branch 6 not taken
     203              142:            "Implicit cast types must be compatible");
     204              142:     Visit(E->getSubExpr());
     205              142:     break;
     206                 : 
     207                 :   case CastExpr::CK_NullToMemberPointer: {
     208                 :     const llvm::Type *PtrDiffTy = 
     209                4:       CGF.ConvertType(CGF.getContext().getPointerDiffType());
     210                 : 
     211                4:     llvm::Value *NullValue = llvm::Constant::getNullValue(PtrDiffTy);
     212                4:     llvm::Value *Ptr = Builder.CreateStructGEP(DestPtr, 0, "ptr");
     213                4:     Builder.CreateStore(NullValue, Ptr, VolatileDest);
     214                 :     
     215                4:     llvm::Value *Adj = Builder.CreateStructGEP(DestPtr, 1, "adj");
     216                4:     Builder.CreateStore(NullValue, Adj, VolatileDest);
     217                 : 
     218                4:     break;
     219                 :   }
     220                 :       
     221                 :   case CastExpr::CK_BitCast: {
     222                 :     // This must be a member function pointer cast.
     223                0:     Visit(E->getSubExpr());
     224                0:     break;
     225                 :   }
     226                 : 
     227                 :   case CastExpr::CK_DerivedToBaseMemberPointer:
     228                 :   case CastExpr::CK_BaseToDerivedMemberPointer: {
     229                4:     QualType SrcType = E->getSubExpr()->getType();
     230                 :     
     231                4:     llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp");
     232                4:     CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified());
     233                 :     
     234                4:     llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
     235                4:     SrcPtr = Builder.CreateLoad(SrcPtr);
     236                 :     
     237                4:     llvm::Value *SrcAdj = Builder.CreateStructGEP(Src, 1, "src.adj");
     238                4:     SrcAdj = Builder.CreateLoad(SrcAdj);
     239                 :     
     240                4:     llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
     241                4:     Builder.CreateStore(SrcPtr, DstPtr, VolatileDest);
     242                 :     
     243                4:     llvm::Value *DstAdj = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
     244                 :     
     245                 :     // Now See if we need to update the adjustment.
     246                 :     const CXXRecordDecl *BaseDecl = 
     247                 :       cast<CXXRecordDecl>(SrcType->getAs<MemberPointerType>()->
     248                4:                           getClass()->getAs<RecordType>()->getDecl());
     249                 :     const CXXRecordDecl *DerivedDecl = 
     250                 :       cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()->
     251                4:                           getClass()->getAs<RecordType>()->getDecl());
                        1: branch 1 taken
                        3: branch 2 taken
     252                4:     if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
     253                1:       std::swap(DerivedDecl, BaseDecl);
     254                 : 
                        2: branch 0 taken
                        2: branch 1 taken
     255                4:     if (llvm::Constant *Adj = 
     256                4:           CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, BaseDecl)) {
                        1: branch 1 taken
                        1: branch 2 taken
     257                2:       if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
     258                1:         SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
     259                 :       else
     260                1:         SrcAdj = Builder.CreateAdd(SrcAdj, Adj, "adj");
     261                 :     }
     262                 :     
     263                4:     Builder.CreateStore(SrcAdj, DstAdj, VolatileDest);
     264                 :     break;
     265                 :   }
     266                 :   }
     267              153: }
     268                 : 
     269               57: void AggExprEmitter::VisitCallExpr(const CallExpr *E) {
                       19: branch 3 taken
                       38: branch 4 taken
     270               57:   if (E->getCallReturnType()->isReferenceType()) {
     271               19:     EmitAggLoadOfLValue(E);
     272               19:     return;
     273                 :   }
     274                 : 
     275                 :   // If the struct doesn't require GC, we can just pass the destination
     276                 :   // directly to EmitCall.
                       36: branch 0 taken
                        2: branch 1 taken
     277               38:   if (!RequiresGCollection) {
     278               36:     CGF.EmitCallExpr(E, ReturnValueSlot(DestPtr, VolatileDest));
     279               36:     return;
     280                 :   }
     281                 :   
     282                2:   RValue RV = CGF.EmitCallExpr(E);
     283                2:   EmitFinalDestCopy(E, RV);
     284                 : }
     285                 : 
     286                4: void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
     287                4:   RValue RV = CGF.EmitObjCMessageExpr(E);
     288                4:   EmitFinalDestCopy(E, RV);
     289                4: }
     290                 : 
     291                4: void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
     292                4:   RValue RV = CGF.EmitObjCPropertyGet(E);
     293                4:   EmitFinalDestCopy(E, RV);
     294                4: }
     295                 : 
     296                 : void AggExprEmitter::VisitObjCImplicitSetterGetterRefExpr(
     297                0:                                    ObjCImplicitSetterGetterRefExpr *E) {
     298                0:   RValue RV = CGF.EmitObjCPropertyGet(E);
     299                0:   EmitFinalDestCopy(E, RV);
     300                0: }
     301                 : 
     302                5: void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
     303                5:   CGF.EmitAnyExpr(E->getLHS(), 0, false, true);
     304                 :   CGF.EmitAggExpr(E->getRHS(), DestPtr, VolatileDest,
     305                5:                   /*IgnoreResult=*/false, IsInitializer);
     306                5: }
     307                 : 
     308               12: void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {
     309                 :   // We have a member function pointer.
     310               12:   const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
     311                 :   (void) MPT;
     312                 :   assert(MPT->getPointeeType()->isFunctionProtoType() &&
                       12: branch 3 taken
                        0: branch 4 not taken
     313               12:          "Unexpected member pointer type!");
     314                 :   
     315               12:   const DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
     316                 :   const CXXMethodDecl *MD = 
     317               12:     cast<CXXMethodDecl>(DRE->getDecl())->getCanonicalDecl();
     318                 : 
     319                 :   const llvm::Type *PtrDiffTy = 
     320               12:     CGF.ConvertType(CGF.getContext().getPointerDiffType());
     321                 : 
     322               12:   llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
     323                 :   llvm::Value *FuncPtr;
     324                 :   
                        5: branch 1 taken
                        7: branch 2 taken
     325               12:   if (MD->isVirtual()) {
     326                 :     int64_t Index = 
     327                5:       CGF.CGM.getVtableInfo().getMethodVtableIndex(MD);
     328                 :     
     329                 :     // Itanium C++ ABI 2.3:
     330                 :     //   For a non-virtual function, this field is a simple function pointer. 
     331                 :     //   For a virtual function, it is 1 plus the virtual table offset 
     332                 :     //   (in bytes) of the function, represented as a ptrdiff_t. 
     333                5:     FuncPtr = llvm::ConstantInt::get(PtrDiffTy, (Index * 8) + 1);
     334                 :   } else {
     335                7:     const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
     336                 :     const llvm::Type *Ty =
     337                 :       CGF.CGM.getTypes().GetFunctionType(CGF.CGM.getTypes().getFunctionInfo(MD),
     338                7:                                          FPT->isVariadic());
     339                7:     llvm::Constant *Fn = CGF.CGM.GetAddrOfFunction(MD, Ty);
     340                7:     FuncPtr = llvm::ConstantExpr::getPtrToInt(Fn, PtrDiffTy);
     341                 :   }
     342               12:   Builder.CreateStore(FuncPtr, DstPtr, VolatileDest);
     343                 : 
     344               12:   llvm::Value *AdjPtr = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
     345                 :   
     346                 :   // The adjustment will always be 0.
     347                 :   Builder.CreateStore(llvm::ConstantInt::get(PtrDiffTy, 0), AdjPtr,
     348               12:                       VolatileDest);
     349               12: }
     350                 : 
     351                1: void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
     352                1:   CGF.EmitCompoundStmt(*E->getSubStmt(), true, DestPtr, VolatileDest);
     353                1: }
     354                 : 
     355                0: void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     356                0:   if (E->getOpcode() == BinaryOperator::PtrMemD ||
     357                 :       E->getOpcode() == BinaryOperator::PtrMemI)
     358                0:     VisitPointerToDataMemberBinaryOperator(E);
     359                 :   else
     360                0:     CGF.ErrorUnsupported(E, "aggregate binary expression");
     361                0: }
     362                 : 
     363                 : void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
     364                0:                                                     const BinaryOperator *E) {
     365                0:   LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
     366                0:   EmitFinalDestCopy(E, LV);
     367                0: }
     368                 : 
     369               42: void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
     370                 :   // For an assignment to work, the value on the right has
     371                 :   // to be compatible with the value on the left.
     372                 :   assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
     373                 :                                                  E->getRHS()->getType())
                       42: branch 6 taken
                        0: branch 7 not taken
     374               42:          && "Invalid assignment");
     375               42:   LValue LHS = CGF.EmitLValue(E->getLHS());
     376                 : 
     377                 :   // We have to special case property setters, otherwise we must have
     378                 :   // a simple lvalue (no aggregates inside vectors, bitfields).
                        7: branch 1 taken
                       35: branch 2 taken
     379               42:   if (LHS.isPropertyRef()) {
     380                7:     llvm::Value *AggLoc = DestPtr;
                        6: branch 0 taken
                        1: branch 1 taken
     381                7:     if (!AggLoc)
     382                6:       AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
     383                7:     CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
     384                 :     CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
     385                7:                             RValue::getAggregate(AggLoc, VolatileDest));
                        0: branch 1 not taken
                       35: branch 2 taken
     386               35:   } else if (LHS.isKVCRef()) {
     387                0:     llvm::Value *AggLoc = DestPtr;
                        0: branch 0 not taken
                        0: branch 1 not taken
     388                0:     if (!AggLoc)
     389                0:       AggLoc = CGF.CreateMemTemp(E->getRHS()->getType());
     390                0:     CGF.EmitAggExpr(E->getRHS(), AggLoc, VolatileDest);
     391                 :     CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
     392                0:                             RValue::getAggregate(AggLoc, VolatileDest));
     393                 :   } else {
     394               35:     bool RequiresGCollection = false;
                       35: branch 2 taken
                        0: branch 3 not taken
     395               35:     if (CGF.getContext().getLangOptions().NeXTRuntime) {
     396               35:       QualType LHSTy = E->getLHS()->getType();
                       31: branch 2 taken
                        4: branch 3 taken
     397               35:       if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>())
     398               31:         RequiresGCollection = FDTTy->getDecl()->hasObjectMember();
     399                 :     }
     400                 :     // Codegen the RHS so that it stores directly into the LHS.
     401                 :     CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
     402               35:                     false, false, RequiresGCollection);
     403               35:     EmitFinalDestCopy(E, LHS, true);
     404                 :   }
     405               42: }
     406                 : 
     407                6: void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
                        0: branch 1 not taken
                        6: branch 2 taken
     408                6:   if (!E->getLHS()) {
     409                0:     CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
     410                0:     return;
     411                 :   }
     412                 : 
     413                6:   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
     414                6:   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
     415                6:   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
     416                 : 
     417                6:   CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
     418                 : 
     419                6:   CGF.BeginConditionalBranch();
     420                6:   CGF.EmitBlock(LHSBlock);
     421                 : 
     422                 :   // Handle the GNU extension for missing LHS.
                        6: branch 1 taken
                        0: branch 2 not taken
     423                6:   assert(E->getLHS() && "Must have LHS for aggregate value");
     424                 : 
     425                6:   Visit(E->getLHS());
     426                6:   CGF.EndConditionalBranch();
     427                6:   CGF.EmitBranch(ContBlock);
     428                 : 
     429                6:   CGF.BeginConditionalBranch();
     430                6:   CGF.EmitBlock(RHSBlock);
     431                 : 
     432                6:   Visit(E->getRHS());
     433                6:   CGF.EndConditionalBranch();
     434                6:   CGF.EmitBranch(ContBlock);
     435                 : 
     436                6:   CGF.EmitBlock(ContBlock);
     437                 : }
     438                 : 
     439                0: void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
     440                0:   Visit(CE->getChosenSubExpr(CGF.getContext()));
     441                0: }
     442                 : 
     443                2: void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
     444                2:   llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
     445                2:   llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
     446                 : 
                        0: branch 0 not taken
                        2: branch 1 taken
     447                2:   if (!ArgPtr) {
     448                0:     CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
     449                0:     return;
     450                 :   }
     451                 : 
     452                2:   EmitFinalDestCopy(VE, LValue::MakeAddr(ArgPtr, Qualifiers()));
     453                 : }
     454                 : 
     455               51: void AggExprEmitter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
     456               51:   llvm::Value *Val = DestPtr;
     457                 : 
                        6: branch 0 taken
                       45: branch 1 taken
     458               51:   if (!Val) {
     459                 :     // Create a temporary variable.
     460                6:     Val = CGF.CreateMemTemp(E->getType(), "tmp");
     461                 : 
     462                 :     // FIXME: volatile
     463                6:     CGF.EmitAggExpr(E->getSubExpr(), Val, false);
     464                 :   } else
     465               45:     Visit(E->getSubExpr());
     466                 : 
     467                 :   // Don't make this a live temporary if we're emitting an initializer expr.
                       37: branch 0 taken
                       14: branch 1 taken
     468               51:   if (!IsInitializer)
     469               37:     CGF.PushCXXTemporary(E->getTemporary(), Val);
     470               51: }
     471                 : 
     472                 : void
     473              751: AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
     474              751:   llvm::Value *Val = DestPtr;
     475                 : 
                        6: branch 0 taken
                      745: branch 1 taken
     476              751:   if (!Val) {
     477                 :     // Create a temporary variable.
     478                6:     Val = CGF.CreateMemTemp(E->getType(), "tmp");
     479                 :   }
     480                 : 
                        1: branch 1 taken
                      750: branch 2 taken
     481              751:   if (E->requiresZeroInitialization())
     482                 :     EmitNullInitializationToLValue(LValue::MakeAddr(Val, 
     483                 :                                                     // FIXME: Qualifiers()?
     484                 :                                                  E->getType().getQualifiers()),
     485                1:                                    E->getType());
     486                 : 
     487              751:   CGF.EmitCXXConstructExpr(Val, E);
     488              751: }
     489                 : 
     490               37: void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
     491               37:   llvm::Value *Val = DestPtr;
     492                 : 
                        5: branch 0 taken
                       32: branch 1 taken
     493               37:   if (!Val) {
     494                 :     // Create a temporary variable.
     495                5:     Val = CGF.CreateMemTemp(E->getType(), "tmp");
     496                 :   }
     497               37:   CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer);
     498               37: }
     499                 : 
     500                3: void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
     501                3:   llvm::Value *Val = DestPtr;
     502                 : 
                        1: branch 0 taken
                        2: branch 1 taken
     503                3:   if (!Val) {
     504                 :     // Create a temporary variable.
     505                1:     Val = CGF.CreateMemTemp(E->getType(), "tmp");
     506                 :   }
     507                3:   LValue LV = LValue::MakeAddr(Val, Qualifiers());
     508                3:   EmitNullInitializationToLValue(LV, E->getType());
     509                3: }
     510                 : 
     511                8: void AggExprEmitter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
     512                8:   llvm::Value *Val = DestPtr;
     513                 : 
                        0: branch 0 not taken
                        8: branch 1 taken
     514                8:   if (!Val) {
     515                 :     // Create a temporary variable.
     516                0:     Val = CGF.CreateMemTemp(E->getType(), "tmp");
     517                 :   }
     518                8:   LValue LV = LValue::MakeAddr(Val, Qualifiers());
     519                8:   EmitNullInitializationToLValue(LV, E->getType());
     520                8: }
     521                 : 
     522                 : void 
     523               69: AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV, QualType T) {
     524                 :   // FIXME: Ignore result?
     525                 :   // FIXME: Are initializers affected by volatile?
                        0: branch 1 not taken
                       69: branch 2 taken
     526               69:   if (isa<ImplicitValueInitExpr>(E)) {
     527                0:     EmitNullInitializationToLValue(LV, T);
                        4: branch 2 taken
                       65: branch 3 taken
     528               69:   } else if (T->isReferenceType()) {
     529                4:     RValue RV = CGF.EmitReferenceBindingToExpr(E, /*IsInitializer=*/false);
     530                4:     CGF.EmitStoreThroughLValue(RV, LV, T);
                        0: branch 2 not taken
                       65: branch 3 taken
     531               65:   } else if (T->isAnyComplexType()) {
     532                0:     CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
                       13: branch 1 taken
                       52: branch 2 taken
     533               65:   } else if (CGF.hasAggregateLLVMType(T)) {
     534               13:     CGF.EmitAnyExpr(E, LV.getAddress(), false);
     535                 :   } else {
     536               52:     CGF.EmitStoreThroughLValue(CGF.EmitAnyExpr(E), LV, T);
     537                 :   }
     538               69: }
     539                 : 
     540               28: void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
                       12: branch 1 taken
                       16: branch 2 taken
     541               28:   if (!CGF.hasAggregateLLVMType(T)) {
     542                 :     // For non-aggregates, we can store zero
     543               12:     llvm::Value *Null = llvm::Constant::getNullValue(CGF.ConvertType(T));
     544               12:     CGF.EmitStoreThroughLValue(RValue::get(Null), LV, T);
     545                 :   } else {
     546                 :     // Otherwise, just memset the whole thing to zero.  This is legal
     547                 :     // because in LLVM, all default initializers are guaranteed to have a
     548                 :     // bit pattern of all zeros.
     549                 :     // FIXME: That isn't true for member pointers!
     550                 :     // There's a potential optimization opportunity in combining
     551                 :     // memsets; that would be easy for arrays, but relatively
     552                 :     // difficult for structures with the current code.
     553               16:     CGF.EmitMemSetToZero(LV.getAddress(), T);
     554                 :   }
     555               28: }
     556                 : 
     557               36: void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
     558                 : #if 0
     559                 :   // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
     560                 :   // (Length of globals? Chunks of zeroed-out space?).
     561                 :   //
     562                 :   // If we can, prefer a copy from a global; this is a lot less code for long
     563                 :   // globals, and it's easier for the current optimizers to analyze.
     564                 :   if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
     565                 :     llvm::GlobalVariable* GV =
     566                 :     new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
     567                 :                              llvm::GlobalValue::InternalLinkage, C, "");
     568                 :     EmitFinalDestCopy(E, LValue::MakeAddr(GV, Qualifiers()));
     569                 :     return;
     570                 :   }
     571                 : #endif
                        0: branch 1 not taken
                       36: branch 2 taken
     572               36:   if (E->hadArrayRangeDesignator()) {
     573                0:     CGF.ErrorUnsupported(E, "GNU array range designator extension");
     574                 :   }
     575                 : 
     576                 :   // Handle initialization of an array.
                        9: branch 3 taken
                       27: branch 4 taken
     577               36:   if (E->getType()->isArrayType()) {
     578                 :     const llvm::PointerType *APType =
     579                9:       cast<llvm::PointerType>(DestPtr->getType());
     580                 :     const llvm::ArrayType *AType =
     581                9:       cast<llvm::ArrayType>(APType->getElementType());
     582                 : 
     583                9:     uint64_t NumInitElements = E->getNumInits();
     584                 : 
                        9: branch 1 taken
                        0: branch 2 not taken
     585                9:     if (E->getNumInits() > 0) {
     586                9:       QualType T1 = E->getType();
     587                9:       QualType T2 = E->getInit(0)->getType();
                        0: branch 2 not taken
                        9: branch 3 taken
     588                9:       if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
     589                0:         EmitAggLoadOfLValue(E->getInit(0));
     590                0:         return;
     591                 :       }
     592                 :     }
     593                 : 
     594                9:     uint64_t NumArrayElements = AType->getNumElements();
     595                9:     QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
     596                9:     ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
     597                 : 
     598                 :     // FIXME: were we intentionally ignoring address spaces and GC attributes?
     599                9:     Qualifiers Quals = CGF.MakeQualifiers(ElementType);
     600                 : 
                       37: branch 0 taken
                        9: branch 1 taken
     601               46:     for (uint64_t i = 0; i != NumArrayElements; ++i) {
     602               37:       llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
                       24: branch 0 taken
                       13: branch 1 taken
     603               37:       if (i < NumInitElements)
     604                 :         EmitInitializationToLValue(E->getInit(i),
     605                 :                                    LValue::MakeAddr(NextVal, Quals), 
     606               24:                                    ElementType);
     607                 :       else
     608                 :         EmitNullInitializationToLValue(LValue::MakeAddr(NextVal, Quals),
     609               13:                                        ElementType);
     610                 :     }
     611                9:     return;
     612                 :   }
     613                 : 
                       27: branch 3 taken
                        0: branch 4 not taken
     614               27:   assert(E->getType()->isRecordType() && "Only support structs/unions here!");
     615                 : 
     616                 :   // Do struct initialization; this code just sets each individual member
     617                 :   // to the approprate value.  This makes bitfield support automatic;
     618                 :   // the disadvantage is that the generated code is more difficult for
     619                 :   // the optimizer, especially with bitfields.
     620               27:   unsigned NumInitElements = E->getNumInits();
     621               27:   RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
     622               27:   unsigned CurInitVal = 0;
     623                 : 
                        0: branch 3 not taken
                       27: branch 4 taken
     624               27:   if (E->getType()->isUnionType()) {
     625                 :     // Only initialize one field of a union. The field itself is
     626                 :     // specified by the initializer list.
                        0: branch 1 not taken
                        0: branch 2 not taken
     627                0:     if (!E->getInitializedFieldInUnion()) {
     628                 :       // Empty union; we have nothing to do.
     629                 : 
     630                 : #ifndef NDEBUG
     631                 :       // Make sure that it's really an empty and not a failure of
     632                 :       // semantic analysis.
                        0: branch 3 not taken
                        0: branch 4 not taken
     633                0:       for (RecordDecl::field_iterator Field = SD->field_begin(),
     634                0:                                    FieldEnd = SD->field_end();
     635                 :            Field != FieldEnd; ++Field)
                        0: branch 2 not taken
                        0: branch 3 not taken
     636                0:         assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
     637                 : #endif
     638                0:       return;
     639                 :     }
     640                 : 
     641                 :     // FIXME: volatility
     642                0:     FieldDecl *Field = E->getInitializedFieldInUnion();
     643                0:     LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
     644                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
     645                0:     if (NumInitElements) {
     646                 :       // Store the initializer into the field
     647                0:       EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
     648                 :     } else {
     649                 :       // Default-initialize to null
     650                0:       EmitNullInitializationToLValue(FieldLoc, Field->getType());
     651                 :     }
     652                 : 
     653                0:     return;
     654                 :   }
     655                 : 
     656                 :   // Here we iterate over the fields; this makes it simpler to both
     657                 :   // default-initialize fields and skip over unnamed fields.
                       45: branch 3 taken
                       27: branch 4 taken
     658               99:   for (RecordDecl::field_iterator Field = SD->field_begin(),
     659               27:                                FieldEnd = SD->field_end();
     660                 :        Field != FieldEnd; ++Field) {
     661                 :     // We're done once we hit the flexible array member
                        0: branch 4 not taken
                       45: branch 5 taken
     662               45:     if (Field->getType()->isIncompleteArrayType())
     663                0:       break;
     664                 : 
                        0: branch 2 not taken
                       45: branch 3 taken
     665               45:     if (Field->isUnnamedBitfield())
     666                0:       continue;
     667                 : 
     668                 :     // FIXME: volatility
     669               45:     LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
     670                 :     // We never generate write-barries for initialized fields.
     671               45:     LValue::SetObjCNonGC(FieldLoc, true);
                       42: branch 0 taken
                        3: branch 1 taken
     672               45:     if (CurInitVal < NumInitElements) {
     673                 :       // Store the initializer into the field
     674                 :       EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc, 
     675               42:                                  Field->getType());
     676                 :     } else {
     677                 :       // We're out of initalizers; default-initialize to null
     678                3:       EmitNullInitializationToLValue(FieldLoc, Field->getType());
     679                 :     }
     680                 :   }
     681                 : }
     682                 : 
     683                 : //===----------------------------------------------------------------------===//
     684                 : //                        Entry Points into this File
     685                 : //===----------------------------------------------------------------------===//
     686                 : 
     687                 : /// EmitAggExpr - Emit the computation of the specified expression of aggregate
     688                 : /// type.  The result is computed into DestPtr.  Note that if DestPtr is null,
     689                 : /// the value of the aggregate expression is not needed.  If VolatileDest is
     690                 : /// true, DestPtr cannot be 0.
     691                 : //
     692                 : // FIXME: Take Qualifiers object.
     693                 : void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
     694                 :                                   bool VolatileDest, bool IgnoreResult,
     695                 :                                   bool IsInitializer,
     696             1110:                                   bool RequiresGCollection) {
     697                 :   assert(E && hasAggregateLLVMType(E->getType()) &&
                     1110: branch 0 taken
                        0: branch 1 not taken
                     1110: branch 4 taken
                        0: branch 5 not taken
     698             1110:          "Invalid aggregate expression to emit");
     699                 :   assert ((DestPtr != 0 || VolatileDest == false)
                      107: branch 0 taken
                     1003: branch 1 taken
                        0: branch 2 not taken
                      107: branch 3 taken
     700             1217:           && "volatile aggregate can't be 0");
     701                 : 
     702                 :   AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer,
     703                 :                  RequiresGCollection)
     704             1110:     .Visit(const_cast<Expr*>(E));
     705             1110: }
     706                 : 
     707               18: LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
                       18: branch 2 taken
                        0: branch 3 not taken
     708               18:   assert(hasAggregateLLVMType(E->getType()) && "Invalid argument!");
     709               18:   Qualifiers Q = MakeQualifiers(E->getType());
     710               18:   llvm::Value *Temp = CreateMemTemp(E->getType());
     711               18:   EmitAggExpr(E, Temp, Q.hasVolatile());
     712               18:   return LValue::MakeAddr(Temp, Q);
     713                 : }
     714                 : 
     715                0: void CodeGenFunction::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
                        0: branch 2 not taken
                        0: branch 3 not taken
     716                0:   assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
     717                 : 
     718                0:   EmitMemSetToZero(DestPtr, Ty);
     719                0: }
     720                 : 
     721                 : void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
     722                 :                                         llvm::Value *SrcPtr, QualType Ty,
     723              204:                                         bool isVolatile) {
                      204: branch 2 taken
                        0: branch 3 not taken
     724              204:   assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
     725                 : 
     726                 :   // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
     727                 :   // C99 6.5.16.1p3, which states "If the value being stored in an object is
     728                 :   // read from another object that overlaps in anyway the storage of the first
     729                 :   // object, then the overlap shall be exact and the two objects shall have
     730                 :   // qualified or unqualified versions of a compatible type."
     731                 :   //
     732                 :   // memcpy is not defined if the source and destination pointers are exactly
     733                 :   // equal, but other compilers do this optimization, and almost every memcpy
     734                 :   // implementation handles this case safely.  If there is a libc that does not
     735                 :   // safely handle this, we can add a target hook.
     736              204:   const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
                      204: branch 1 taken
                        0: branch 2 not taken
     737              204:   if (DestPtr->getType() != BP)
     738              204:     DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
                      204: branch 1 taken
                        0: branch 2 not taken
     739              204:   if (SrcPtr->getType() != BP)
     740              204:     SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
     741                 : 
     742                 :   // Get size and alignment info for this aggregate.
     743              204:   std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
     744                 : 
     745                 :   // FIXME: Handle variable sized types.
     746                 :   const llvm::Type *IntPtr =
     747              204:           llvm::IntegerType::get(VMContext, LLVMPointerWidth);
     748                 : 
     749                 :   // FIXME: If we have a volatile struct, the optimizer can remove what might
     750                 :   // appear to be `extra' memory ops:
     751                 :   //
     752                 :   // volatile struct { int i; } a, b;
     753                 :   //
     754                 :   // int main() {
     755                 :   //   a = b;
     756                 :   //   a = b;
     757                 :   // }
     758                 :   //
     759                 :   // we need to use a differnt call here.  We use isVolatile to indicate when
     760                 :   // either the source or the destination is volatile.
     761                 :   Builder.CreateCall4(CGM.getMemCpyFn(),
     762                 :                       DestPtr, SrcPtr,
     763                 :                       // TypeInfo.first describes size in bits.
     764                 :                       llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
     765                 :                       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
     766              204:                                              TypeInfo.second/8));
     767              204: }

Generated: 2010-02-10 01:31 by zcov