lib/IRGen/GenMeta.cpp
static llvm::Value *emitLoadOfHeapMetadataRef(IRGenFunction &IGF,
                                              llvm::Value *object,
                                              IsaEncoding isaEncoding,
                                              bool suppressCast) {
  switch (isaEncoding) {
  case IsaEncoding::Pointer: {
    // Drill into the object pointer.  Rather than bitcasting, we make
    // an effort to do something that should explode if we get something
    // mistyped.
    llvm::StructType *structTy =
      cast<llvm::StructType>(
        cast<llvm::PointerType>(object->getType())->getElementType());

    llvm::Value *slot;

    // We need a bitcast if we're dealing with an opaque class.
    if (structTy->isOpaque()) {
      auto metadataPtrPtrTy = IGF.IGM.TypeMetadataPtrTy->getPointerTo();
      slot = IGF.Builder.CreateBitCast(object, metadataPtrPtrTy);

    // Otherwise, make a GEP.
    } else {
      auto zero = llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0);

      SmallVector<llvm::Value*, 4> indexes;
      indexes.push_back(zero);
      do {
        indexes.push_back(zero);

        // Keep drilling down to the first element type.
        auto eltTy = structTy->getElementType(0);
        assert(isa<llvm::StructType>(eltTy) || eltTy == IGF.IGM.TypeMetadataPtrTy);
        structTy = dyn_cast<llvm::StructType>(eltTy);
      } while (structTy != nullptr);

      slot = IGF.Builder.CreateInBoundsGEP(object, indexes);

      if (!suppressCast) {
        slot = IGF.Builder.CreateBitCast(slot,
                                    IGF.IGM.TypeMetadataPtrTy->getPointerTo());
      }
    }

    auto metadata = IGF.Builder.CreateLoad(Address(slot,
                                               IGF.IGM.getPointerAlignment()));
    if (IGF.IGM.EnableValueNames && object->hasName())
      metadata->setName(llvm::Twine(object->getName()) + ".metadata");
    return metadata;
  }
      
  case IsaEncoding::ObjC: {
    // Feed the object pointer to object_getClass.
    llvm::Value *objcClass = emitLoadOfObjCHeapMetadataRef(IGF, object);
    objcClass = IGF.Builder.CreateBitCast(objcClass, IGF.IGM.TypeMetadataPtrTy);
    return objcClass;
  }
  }

  llvm_unreachable("Not a valid IsaEncoding.");
}
/// Given a pointer to a heap object (i.e. definitely not a tagged
/// pointer), load its heap metadata pointer.
Given a pointer to a heap object , load its heap metadata pointer.
Given a pointer to a heap object load its heap metadata pointer .
static llvm::Value *emitLoadOfHeapMetadataRef(IRGenFunction &IGF,
                                              llvm::Value *object,
                                              IsaEncoding isaEncoding,
                                              bool suppressCast) {
  switch (isaEncoding) {
  case IsaEncoding::Pointer: {
    llvm::StructType *structTy =
      cast<llvm::StructType>(
        cast<llvm::PointerType>(object->getType())->getElementType());
    llvm::Value *slot;
    if (structTy->isOpaque()) {
      auto metadataPtrPtrTy = IGF.IGM.TypeMetadataPtrTy->getPointerTo();
      slot = IGF.Builder.CreateBitCast(object, metadataPtrPtrTy);
    } else {
      auto zero = llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0);
      SmallVector<llvm::Value*, 4> indexes;
      indexes.push_back(zero);
      do {
        indexes.push_back(zero);
        auto eltTy = structTy->getElementType(0);
        assert(isa<llvm::StructType>(eltTy) || eltTy == IGF.IGM.TypeMetadataPtrTy);
        structTy = dyn_cast<llvm::StructType>(eltTy);
      } while (structTy != nullptr);
      slot = IGF.Builder.CreateInBoundsGEP(object, indexes);
      if (!suppressCast) {
        slot = IGF.Builder.CreateBitCast(slot,
                                    IGF.IGM.TypeMetadataPtrTy->getPointerTo());
      }
    }
    auto metadata = IGF.Builder.CreateLoad(Address(slot,
                                               IGF.IGM.getPointerAlignment()));
    if (IGF.IGM.EnableValueNames && object->hasName())
      metadata->setName(llvm::Twine(object->getName()) + ".metadata");
    return metadata;
  }
  case IsaEncoding::ObjC: {
    llvm::Value *objcClass = emitLoadOfObjCHeapMetadataRef(IGF, object);
    objcClass = IGF.Builder.CreateBitCast(objcClass, IGF.IGM.TypeMetadataPtrTy);
    return objcClass;
  }
  }
  llvm_unreachable("Not a valid IsaEncoding.");
}
static llvm :: Value * emitLoadOfHeapMetadataRef ( IRGenFunction & IGF , llvm :: Value * object , IsaEncoding isaEncoding , bool suppressCast ) { switch ( isaEncoding ) { case IsaEncoding :: Pointer : { llvm :: StructType * structTy = cast < llvm :: StructType > ( cast < llvm :: PointerType > ( object -> getType ( ) ) -> getElementType ( ) ) ; llvm :: Value * slot ; if ( structTy -> isOpaque ( ) ) { auto metadataPtrPtrTy = IGF . IGM . TypeMetadataPtrTy -> getPointerTo ( ) ; slot = IGF . Builder . CreateBitCast ( object , metadataPtrPtrTy ) ; } else { auto zero = llvm :: ConstantInt :: get ( IGF . IGM . Int32Ty , 0 ) ; SmallVector < llvm :: Value * , 4 > indexes ; indexes . push_back ( zero ) ; do { indexes . push_back ( zero ) ; auto eltTy = structTy -> getElementType ( 0 ) ; assert ( isa < llvm :: StructType > ( eltTy ) || eltTy == IGF . IGM . TypeMetadataPtrTy ) ; structTy = dyn_cast < llvm :: StructType > ( eltTy ) ; } while ( structTy != nullptr ) ; slot = IGF . Builder . CreateInBoundsGEP ( object , indexes ) ; if ( ! suppressCast ) { slot = IGF . Builder . CreateBitCast ( slot , IGF . IGM . TypeMetadataPtrTy -> getPointerTo ( ) ) ; } } auto metadata = IGF . Builder . CreateLoad ( Address ( slot , IGF . IGM . getPointerAlignment ( ) ) ) ; if ( IGF . IGM . EnableValueNames && object -> hasName ( ) ) metadata -> setName ( llvm :: Twine ( object -> getName ( ) ) + " " ) ; return metadata ; } case IsaEncoding :: ObjC : { llvm :: Value * objcClass = emitLoadOfObjCHeapMetadataRef ( IGF , object ) ; objcClass = IGF . Builder . CreateBitCast ( objcClass , IGF . IGM . TypeMetadataPtrTy ) ; return objcClass ; } } llvm_unreachable ( " " ) ; }
Given a pointer to a heap object (i.e.
Given a pointer to a heap object ( i . e .
// Drill into the object pointer.  Rather than bitcasting, we make // an effort to do something that should explode if we get something // mistyped. // We need a bitcast if we're dealing with an opaque class. // Otherwise, make a GEP. // Keep drilling down to the first element type. // Feed the object pointer to object_getClass.