Пример #1
0
llvm::Function::arg_iterator
CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
                                    llvm::Function::arg_iterator AI) {
  const RecordType *RT = Ty->getAsStructureType();
  assert(RT && "Can only expand structure types.");

  RecordDecl *RD = RT->getDecl();
  assert(LV.isSimple() &&
         "Unexpected non-simple lvalue during struct expansion.");
  llvm::Value *Addr = LV.getAddress();
  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
         i != e; ++i) {
    FieldDecl *FD = *i;
    QualType FT = FD->getType();

    // FIXME: What are the right qualifiers here?
    LValue LV = EmitLValueForField(Addr, FD, false, 0);
    if (CodeGenFunction::hasAggregateLLVMType(FT)) {
      AI = ExpandTypeFromArgs(FT, LV, AI);
    } else {
      EmitStoreThroughLValue(RValue::get(AI), LV, FT);
      ++AI;
    }
  }

  return AI;
}
Пример #2
0
void
CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
                                  llvm::SmallVector<llvm::Value*, 16> &Args) {
  const RecordType *RT = Ty->getAsStructureType();
  assert(RT && "Can only expand structure types.");

  RecordDecl *RD = RT->getDecl();
  assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
  llvm::Value *Addr = RV.getAggregateAddr();
  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
         i != e; ++i) {
    FieldDecl *FD = *i;
    QualType FT = FD->getType();

    // FIXME: What are the right qualifiers here?
    LValue LV = EmitLValueForField(Addr, FD, false, 0);
    if (CodeGenFunction::hasAggregateLLVMType(FT)) {
      ExpandTypeToArgs(FT, RValue::getAggregate(LV.getAddress()), Args);
    } else {
      RValue RV = EmitLoadOfLValue(LV, FT);
      assert(RV.isScalar() &&
             "Unexpected non-scalar rvalue during struct expansion.");
      Args.push_back(RV.getScalarVal());
    }
  }
}
void Sema::ActOnTagResumeDefinitionRoger(Scope *S, Decl *TagD) {
    //TagDecl *Tag = cast<TagDecl>(TagD);
    RecordDecl *rd = dyn_cast<RecordDecl>(TagD);
    if (rd) {
        rd->resumeDefinitionRoger();
    }

    FieldCollector->StartClass();
}
Пример #4
0
 //--------------------------------------------------------- 
 void VisitExpr(Expr* Node)
 {
   for (RecordDecl::field_iterator i = RD->field_begin(), 
        e = RD->field_end(); i != e; ++i)
   {
     compoundStmts.push_back(Assign_(
       MemberPoint_(Paren_(Clone_(LHS)), *i), 
       MemberPoint_(Paren_(Clone_(Node)), *i)));
   }
 }
Пример #5
0
/// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
/// C++ if/switch/while/for statement.
/// e.g: "if (int x = f()) {...}"
Action::OwningExprResult
Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc,
                                       Declarator &D,
                                       SourceLocation EqualLoc,
                                       ExprArg AssignExprVal) {
  assert(AssignExprVal.get() && "Null assignment expression");

  // C++ 6.4p2:
  // The declarator shall not specify a function or an array.
  // The type-specifier-seq shall not contain typedef and shall not declare a
  // new class or enumeration.

  assert(D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
         "Parser allowed 'typedef' as storage class of condition decl.");

  QualType Ty = GetTypeForDeclarator(D, S);
  
  if (Ty->isFunctionType()) { // The declarator shall not specify a function...
    // We exit without creating a CXXConditionDeclExpr because a FunctionDecl
    // would be created and CXXConditionDeclExpr wants a VarDecl.
    return ExprError(Diag(StartLoc, diag::err_invalid_use_of_function_type)
      << SourceRange(StartLoc, EqualLoc));
  } else if (Ty->isArrayType()) { // ...or an array.
    Diag(StartLoc, diag::err_invalid_use_of_array_type)
      << SourceRange(StartLoc, EqualLoc);
  } else if (const RecordType *RT = Ty->getAsRecordType()) {
    RecordDecl *RD = RT->getDecl();
    // The type-specifier-seq shall not declare a new class...
    if (RD->isDefinition() &&
        (RD->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(RD))))
      Diag(RD->getLocation(), diag::err_type_defined_in_condition);
  } else if (const EnumType *ET = Ty->getAsEnumType()) {
    EnumDecl *ED = ET->getDecl();
    // ...or enumeration.
    if (ED->isDefinition() &&
        (ED->getIdentifier() == 0 || S->isDeclScope(DeclPtrTy::make(ED))))
      Diag(ED->getLocation(), diag::err_type_defined_in_condition);
  }

  DeclPtrTy Dcl = ActOnDeclarator(S, D, DeclPtrTy());
  if (!Dcl)
    return ExprError();
  AddInitializerToDecl(Dcl, move(AssignExprVal));

  // Mark this variable as one that is declared within a conditional.
  // We know that the decl had to be a VarDecl because that is the only type of
  // decl that can be assigned and the grammar requires an '='.
  VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>());
  VD->setDeclaredInCondition(true);
  return Owned(new (Context) CXXConditionDeclExpr(StartLoc, EqualLoc, VD));
}
Пример #6
0
/// GetNumNonZeroBytesInInit - Get an approximate count of the number of
/// non-zero bytes that will be stored when outputting the initializer for the
/// specified initializer expression.
static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
  E = E->IgnoreParens();

  // 0 and 0.0 won't require any non-zero stores!
  if (isSimpleZero(E, CGF)) return CharUnits::Zero();

  // If this is an initlist expr, sum up the size of sizes of the (present)
  // elements.  If this is something weird, assume the whole thing is non-zero.
  const InitListExpr *ILE = dyn_cast<InitListExpr>(E);
  if (ILE == 0 || !CGF.getTypes().isZeroInitializable(ILE->getType()))
    return CGF.getContext().getTypeSizeInChars(E->getType());
  
  // InitListExprs for structs have to be handled carefully.  If there are
  // reference members, we need to consider the size of the reference, not the
  // referencee.  InitListExprs for unions and arrays can't have references.
  if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
    if (!RT->isUnionType()) {
      RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
      CharUnits NumNonZeroBytes = CharUnits::Zero();
      
      unsigned ILEElement = 0;
      for (RecordDecl::field_iterator Field = SD->field_begin(),
           FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) {
        // We're done once we hit the flexible array member or run out of
        // InitListExpr elements.
        if (Field->getType()->isIncompleteArrayType() ||
            ILEElement == ILE->getNumInits())
          break;
        if (Field->isUnnamedBitfield())
          continue;

        const Expr *E = ILE->getInit(ILEElement++);
        
        // Reference values are always non-null and have the width of a pointer.
        if (Field->getType()->isReferenceType())
          NumNonZeroBytes += CGF.getContext().toCharUnitsFromBits(
              CGF.getContext().getTargetInfo().getPointerWidth(0));
        else
          NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF);
      }
      
      return NumNonZeroBytes;
    }
  }
  
  
  CharUnits NumNonZeroBytes = CharUnits::Zero();
  for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
    NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF);
  return NumNonZeroBytes;
}
Пример #7
0
bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
                                           CXXBasePath &Path,
                                           DeclarationName Name) {
  RecordDecl *BaseRecord =
      Specifier->getType()->castAs<RecordType>()->getDecl();

  for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();
       Path.Decls = Path.Decls.slice(1)) {
    if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPReduction))
      return true;
  }

  return false;
}
Пример #8
0
bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {
  RecordDecl *RD = nullptr;
  if (auto *LSI = dyn_cast<LambdaScopeInfo>(this))
    RD = LSI->Lambda;
  else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(this))
    RD = CRSI->TheRecordDecl;

  if (RD)
    for (auto *FD : RD->fields()) {
      if (FD->hasCapturedVLAType() && FD->getCapturedVLAType() == VAT)
        return true;
    }
  return false;
}
Пример #9
0
/// \brief True if the given aggregate type requires special GC API calls.
bool AggExprEmitter::TypeRequiresGCollection(QualType T) {
  // Only record types have members that might require garbage collection.
  const RecordType *RecordTy = T->getAs<RecordType>();
  if (!RecordTy) return false;

  // Don't mess with non-trivial C++ types.
  RecordDecl *Record = RecordTy->getDecl();
  if (isa<CXXRecordDecl>(Record) &&
      (!cast<CXXRecordDecl>(Record)->hasTrivialCopyConstructor() ||
       !cast<CXXRecordDecl>(Record)->hasTrivialDestructor()))
    return false;

  // Check whether the type has an object member.
  return Record->hasObjectMember();
}
Пример #10
0
bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier, 
                                  CXXBasePath &Path,
                                  void *Name) {
  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();

  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
  for (Path.Decls = BaseRecord->lookup(N);
       Path.Decls.first != Path.Decls.second;
       ++Path.Decls.first) {
    if ((*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
      return true;
  }

  return false;
}
Пример #11
0
bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 
                                       CXXBasePath &Path,
                                       void *Name) {
  RecordDecl *BaseRecord =
    Specifier->getType()->castAs<RecordType>()->getDecl();
  
  const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
  for (Path.Decls = BaseRecord->lookup(N);
       !Path.Decls.empty();
       Path.Decls = Path.Decls.slice(1)) {
    if (Path.Decls.front()->isInIdentifierNamespace(IDNS))
      return true;
  }
  
  return false;
}
Пример #12
0
bool CXXRecordDecl::
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, 
                              CXXBasePath &Path,
                              DeclarationName Name) {
  RecordDecl *BaseRecord =
    Specifier->getType()->castAs<RecordType>()->getDecl();
  
  for (Path.Decls = BaseRecord->lookup(Name);
       !Path.Decls.empty();
       Path.Decls = Path.Decls.slice(1)) {
    // FIXME: Refactor the "is it a nested-name-specifier?" check
    if (isa<TypedefNameDecl>(Path.Decls.front()) ||
        Path.Decls.front()->isInIdentifierNamespace(IDNS_Tag))
      return true;
  }
  
  return false;
}
Пример #13
0
bool CXXRecordDecl::
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, 
                              CXXBasePath &Path,
                              void *Name) {
  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
  
  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
  for (Path.Decls = BaseRecord->lookup(N);
       Path.Decls.first != Path.Decls.second;
       ++Path.Decls.first) {
    // FIXME: Refactor the "is it a nested-name-specifier?" check
    if (isa<TypedefNameDecl>(*Path.Decls.first) ||
        (*Path.Decls.first)->isInIdentifierNamespace(IDNS_Tag))
      return true;
  }
  
  return false;
}
Пример #14
0
  //--------------------------------------------------------- 
  void VisitInitListExpr(InitListExpr *RHS) 
  {
    unsigned elementNo = 0;
    for (RecordDecl::field_iterator i = RD->field_begin(), 
         e = RD->field_end(); i != e; ++i)
    {
      // how to handle?
      if (i->isUnnamedBitfield())
        continue;
    
      compoundStmts.push_back(Assign_(
        MemberPoint_(Paren_(Clone_(LHS)), *i), 
        elementNo < RHS->getNumInits() ?        
          Clone_ (RHS->getInit(elementNo)) : 
          Int_(0)));

      elementNo++;
    }
  }
Пример #15
0
bool ATSCollectionVisitor::VisitMemberExpr(MemberExpr *ME)
{
  ValueDecl *OrigDecl = ME->getMemberDecl();
  FieldDecl *FD = dyn_cast<FieldDecl>(OrigDecl);

  if (!FD) {
    // in C++, getMemberDecl returns a CXXMethodDecl.
    if (TransformationManager::isCXXLangOpt())
      return true;
    TransAssert(0 && "Bad FD!\n");
  }

  const Type *T = FD->getType().getTypePtr();
  if (!T->isScalarType())
    return true;

  RecordDecl *RD = FD->getParent();
  TransAssert(RD && "NULL RecordDecl!");
  if (!RD->isStruct() && !RD->isUnion())
    return true;

  ConsumerInstance->addOneExpr(ME);
  return true;
}
Пример #16
0
void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
#if 0
  // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
  // (Length of globals? Chunks of zeroed-out space?).
  //
  // If we can, prefer a copy from a global; this is a lot less code for long
  // globals, and it's easier for the current optimizers to analyze.
  if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
    llvm::GlobalVariable* GV =
    new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
                             llvm::GlobalValue::InternalLinkage, C, "");
    EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType()));
    return;
  }
#endif
  if (E->hadArrayRangeDesignator()) {
    CGF.ErrorUnsupported(E, "GNU array range designator extension");
  }

  // Handle initialization of an array.
  if (E->getType()->isArrayType()) {
    const llvm::PointerType *APType =
      cast<llvm::PointerType>(DestPtr->getType());
    const llvm::ArrayType *AType =
      cast<llvm::ArrayType>(APType->getElementType());

    uint64_t NumInitElements = E->getNumInits();

    if (E->getNumInits() > 0) {
      QualType T1 = E->getType();
      QualType T2 = E->getInit(0)->getType();
      if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
        EmitAggLoadOfLValue(E->getInit(0));
        return;
      }
    }

    uint64_t NumArrayElements = AType->getNumElements();
    QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
    ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();

    // FIXME: were we intentionally ignoring address spaces and GC attributes?

    for (uint64_t i = 0; i != NumArrayElements; ++i) {
      llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
      LValue LV = CGF.MakeAddrLValue(NextVal, ElementType);
      if (i < NumInitElements)
        EmitInitializationToLValue(E->getInit(i), LV, ElementType);

      else
        EmitNullInitializationToLValue(LV, ElementType);
    }
    return;
  }

  assert(E->getType()->isRecordType() && "Only support structs/unions here!");

  // Do struct initialization; this code just sets each individual member
  // to the approprate value.  This makes bitfield support automatic;
  // the disadvantage is that the generated code is more difficult for
  // the optimizer, especially with bitfields.
  unsigned NumInitElements = E->getNumInits();
  RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl();
  
  // If we're initializing the whole aggregate, just do it in place.
  // FIXME: This is a hack around an AST bug (PR6537).
  if (NumInitElements == 1 && E->getType() == E->getInit(0)->getType()) {
    EmitInitializationToLValue(E->getInit(0),
                               CGF.MakeAddrLValue(DestPtr, E->getType()),
                               E->getType());
    return;
  }
  
  
  if (E->getType()->isUnionType()) {
    // Only initialize one field of a union. The field itself is
    // specified by the initializer list.
    if (!E->getInitializedFieldInUnion()) {
      // Empty union; we have nothing to do.

#ifndef NDEBUG
      // Make sure that it's really an empty and not a failure of
      // semantic analysis.
      for (RecordDecl::field_iterator Field = SD->field_begin(),
                                   FieldEnd = SD->field_end();
           Field != FieldEnd; ++Field)
        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
#endif
      return;
    }

    // FIXME: volatility
    FieldDecl *Field = E->getInitializedFieldInUnion();
    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);

    if (NumInitElements) {
      // Store the initializer into the field
      EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType());
    } else {
      // Default-initialize to null
      EmitNullInitializationToLValue(FieldLoc, Field->getType());
    }

    return;
  }

  // Here we iterate over the fields; this makes it simpler to both
  // default-initialize fields and skip over unnamed fields.
  unsigned CurInitVal = 0;
  for (RecordDecl::field_iterator Field = SD->field_begin(),
                               FieldEnd = SD->field_end();
       Field != FieldEnd; ++Field) {
    // We're done once we hit the flexible array member
    if (Field->getType()->isIncompleteArrayType())
      break;

    if (Field->isUnnamedBitfield())
      continue;

    // FIXME: volatility
    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0);
    // We never generate write-barries for initialized fields.
    FieldLoc.setNonGC(true);
    if (CurInitVal < NumInitElements) {
      // Store the initializer into the field.
      EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
                                 Field->getType());
    } else {
      // We're out of initalizers; default-initialize to null
      EmitNullInitializationToLValue(FieldLoc, Field->getType());
    }
  }
}
Пример #17
0
void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
#if 0
  // FIXME: Assess perf here?  Figure out what cases are worth optimizing here
  // (Length of globals? Chunks of zeroed-out space?).
  //
  // If we can, prefer a copy from a global; this is a lot less code for long
  // globals, and it's easier for the current optimizers to analyze.
  if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) {
    llvm::GlobalVariable* GV =
    new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true,
                             llvm::GlobalValue::InternalLinkage, C, "");
    EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType()));
    return;
  }
#endif
  if (E->hadArrayRangeDesignator())
    CGF.ErrorUnsupported(E, "GNU array range designator extension");

  llvm::Value *DestPtr = Dest.getAddr();

  // Handle initialization of an array.
  if (E->getType()->isArrayType()) {
    llvm::PointerType *APType =
      cast<llvm::PointerType>(DestPtr->getType());
    llvm::ArrayType *AType =
      cast<llvm::ArrayType>(APType->getElementType());

    uint64_t NumInitElements = E->getNumInits();

    if (E->getNumInits() > 0) {
      QualType T1 = E->getType();
      QualType T2 = E->getInit(0)->getType();
      if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) {
        EmitAggLoadOfLValue(E->getInit(0));
        return;
      }
    }

    uint64_t NumArrayElements = AType->getNumElements();
    assert(NumInitElements <= NumArrayElements);

    QualType elementType = E->getType().getCanonicalType();
    elementType = CGF.getContext().getQualifiedType(
                    cast<ArrayType>(elementType)->getElementType(),
                    elementType.getQualifiers() + Dest.getQualifiers());

    // DestPtr is an array*.  Construct an elementType* by drilling
    // down a level.
    llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
    llvm::Value *indices[] = { zero, zero };
    llvm::Value *begin =
      Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin");

    // Exception safety requires us to destroy all the
    // already-constructed members if an initializer throws.
    // For that, we'll need an EH cleanup.
    QualType::DestructionKind dtorKind = elementType.isDestructedType();
    llvm::AllocaInst *endOfInit = 0;
    EHScopeStack::stable_iterator cleanup;
    llvm::Instruction *cleanupDominator = 0;
    if (CGF.needsEHCleanup(dtorKind)) {
      // In principle we could tell the cleanup where we are more
      // directly, but the control flow can get so varied here that it
      // would actually be quite complex.  Therefore we go through an
      // alloca.
      endOfInit = CGF.CreateTempAlloca(begin->getType(),
                                       "arrayinit.endOfInit");
      cleanupDominator = Builder.CreateStore(begin, endOfInit);
      CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
                                           CGF.getDestroyer(dtorKind));
      cleanup = CGF.EHStack.stable_begin();

    // Otherwise, remember that we didn't need a cleanup.
    } else {
      dtorKind = QualType::DK_none;
    }

    llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);

    // The 'current element to initialize'.  The invariants on this
    // variable are complicated.  Essentially, after each iteration of
    // the loop, it points to the last initialized element, except
    // that it points to the beginning of the array before any
    // elements have been initialized.
    llvm::Value *element = begin;

    // Emit the explicit initializers.
    for (uint64_t i = 0; i != NumInitElements; ++i) {
      // Advance to the next element.
      if (i > 0) {
        element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element");

        // Tell the cleanup that it needs to destroy up to this
        // element.  TODO: some of these stores can be trivially
        // observed to be unnecessary.
        if (endOfInit) Builder.CreateStore(element, endOfInit);
      }

      LValue elementLV = CGF.MakeAddrLValue(element, elementType);
      EmitInitializationToLValue(E->getInit(i), elementLV);
    }

    // Check whether there's a non-trivial array-fill expression.
    // Note that this will be a CXXConstructExpr even if the element
    // type is an array (or array of array, etc.) of class type.
    Expr *filler = E->getArrayFiller();
    bool hasTrivialFiller = true;
    if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) {
      assert(cons->getConstructor()->isDefaultConstructor());
      hasTrivialFiller = cons->getConstructor()->isTrivial();
    }

    // Any remaining elements need to be zero-initialized, possibly
    // using the filler expression.  We can skip this if the we're
    // emitting to zeroed memory.
    if (NumInitElements != NumArrayElements &&
        !(Dest.isZeroed() && hasTrivialFiller &&
          CGF.getTypes().isZeroInitializable(elementType))) {

      // Use an actual loop.  This is basically
      //   do { *array++ = filler; } while (array != end);

      // Advance to the start of the rest of the array.
      if (NumInitElements) {
        element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start");
        if (endOfInit) Builder.CreateStore(element, endOfInit);
      }

      // Compute the end of the array.
      llvm::Value *end = Builder.CreateInBoundsGEP(begin,
                        llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements),
                                                   "arrayinit.end");

      llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
      llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");

      // Jump into the body.
      CGF.EmitBlock(bodyBB);
      llvm::PHINode *currentElement =
        Builder.CreatePHI(element->getType(), 2, "arrayinit.cur");
      currentElement->addIncoming(element, entryBB);

      // Emit the actual filler expression.
      LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType);
      if (filler)
        EmitInitializationToLValue(filler, elementLV);
      else
        EmitNullInitializationToLValue(elementLV);

      // Move on to the next element.
      llvm::Value *nextElement =
        Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next");

      // Tell the EH cleanup that we finished with the last element.
      if (endOfInit) Builder.CreateStore(nextElement, endOfInit);

      // Leave the loop if we're done.
      llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,
                                               "arrayinit.done");
      llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
      Builder.CreateCondBr(done, endBB, bodyBB);
      currentElement->addIncoming(nextElement, Builder.GetInsertBlock());

      CGF.EmitBlock(endBB);
    }

    // Leave the partial-array cleanup if we entered one.
    if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);

    return;
  }

  assert(E->getType()->isRecordType() && "Only support structs/unions here!");

  // Do struct initialization; this code just sets each individual member
  // to the approprate value.  This makes bitfield support automatic;
  // the disadvantage is that the generated code is more difficult for
  // the optimizer, especially with bitfields.
  unsigned NumInitElements = E->getNumInits();
  RecordDecl *record = E->getType()->castAs<RecordType>()->getDecl();
  
  if (record->isUnion()) {
    // Only initialize one field of a union. The field itself is
    // specified by the initializer list.
    if (!E->getInitializedFieldInUnion()) {
      // Empty union; we have nothing to do.

#ifndef NDEBUG
      // Make sure that it's really an empty and not a failure of
      // semantic analysis.
      for (RecordDecl::field_iterator Field = record->field_begin(),
                                   FieldEnd = record->field_end();
           Field != FieldEnd; ++Field)
        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
#endif
      return;
    }

    // FIXME: volatility
    FieldDecl *Field = E->getInitializedFieldInUnion();

    LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
    if (NumInitElements) {
      // Store the initializer into the field
      EmitInitializationToLValue(E->getInit(0), FieldLoc);
    } else {
      // Default-initialize to null.
      EmitNullInitializationToLValue(FieldLoc);
    }

    return;
  }

  // We'll need to enter cleanup scopes in case any of the member
  // initializers throw an exception.
  SmallVector<EHScopeStack::stable_iterator, 16> cleanups;
  llvm::Instruction *cleanupDominator = 0;

  // Here we iterate over the fields; this makes it simpler to both
  // default-initialize fields and skip over unnamed fields.
  unsigned curInitIndex = 0;
  for (RecordDecl::field_iterator field = record->field_begin(),
                               fieldEnd = record->field_end();
       field != fieldEnd; ++field) {
    // We're done once we hit the flexible array member.
    if (field->getType()->isIncompleteArrayType())
      break;

    // Always skip anonymous bitfields.
    if (field->isUnnamedBitfield())
      continue;

    // We're done if we reach the end of the explicit initializers, we
    // have a zeroed object, and the rest of the fields are
    // zero-initializable.
    if (curInitIndex == NumInitElements && Dest.isZeroed() &&
        CGF.getTypes().isZeroInitializable(E->getType()))
      break;
    
    // FIXME: volatility
    LValue LV = CGF.EmitLValueForFieldInitialization(DestPtr, *field, 0);
    // We never generate write-barries for initialized fields.
    LV.setNonGC(true);
    
    if (curInitIndex < NumInitElements) {
      // Store the initializer into the field.
      EmitInitializationToLValue(E->getInit(curInitIndex++), LV);
    } else {
      // We're out of initalizers; default-initialize to null
      EmitNullInitializationToLValue(LV);
    }

    // Push a destructor if necessary.
    // FIXME: if we have an array of structures, all explicitly
    // initialized, we can end up pushing a linear number of cleanups.
    bool pushedCleanup = false;
    if (QualType::DestructionKind dtorKind
          = field->getType().isDestructedType()) {
      assert(LV.isSimple());
      if (CGF.needsEHCleanup(dtorKind)) {
        if (!cleanupDominator)
          cleanupDominator = CGF.Builder.CreateUnreachable(); // placeholder

        CGF.pushDestroy(EHCleanup, LV.getAddress(), field->getType(),
                        CGF.getDestroyer(dtorKind), false);
        cleanups.push_back(CGF.EHStack.stable_begin());
        pushedCleanup = true;
      }
    }
    
    // If the GEP didn't get used because of a dead zero init or something
    // else, clean it up for -O0 builds and general tidiness.
    if (!pushedCleanup && LV.isSimple()) 
      if (llvm::GetElementPtrInst *GEP =
            dyn_cast<llvm::GetElementPtrInst>(LV.getAddress()))
        if (GEP->use_empty())
          GEP->eraseFromParent();
  }

  // Deactivate all the partial cleanups in reverse order, which
  // generally means popping them.
  for (unsigned i = cleanups.size(); i != 0; --i)
    CGF.DeactivateCleanupBlock(cleanups[i-1], cleanupDominator);

  // Destroy the placeholder if we made one.
  if (cleanupDominator)
    cleanupDominator->eraseFromParent();
}
Пример #18
0
void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
                                        llvm::Value *SrcPtr, QualType Ty,
                                        bool isVolatile, unsigned Alignment) {
  assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");

  if (getContext().getLangOptions().CPlusPlus) {
    if (const RecordType *RT = Ty->getAs<RecordType>()) {
      CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
      assert((Record->hasTrivialCopyConstructor() || 
              Record->hasTrivialCopyAssignment() ||
              Record->hasTrivialMoveConstructor() ||
              Record->hasTrivialMoveAssignment()) &&
             "Trying to aggregate-copy a type without a trivial copy "
             "constructor or assignment operator");
      // Ignore empty classes in C++.
      if (Record->isEmpty())
        return;
    }
  }
  
  // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
  // C99 6.5.16.1p3, which states "If the value being stored in an object is
  // read from another object that overlaps in anyway the storage of the first
  // object, then the overlap shall be exact and the two objects shall have
  // qualified or unqualified versions of a compatible type."
  //
  // memcpy is not defined if the source and destination pointers are exactly
  // equal, but other compilers do this optimization, and almost every memcpy
  // implementation handles this case safely.  If there is a libc that does not
  // safely handle this, we can add a target hook.

  // Get size and alignment info for this aggregate.
  std::pair<CharUnits, CharUnits> TypeInfo = 
    getContext().getTypeInfoInChars(Ty);

  if (!Alignment)
    Alignment = TypeInfo.second.getQuantity();

  // FIXME: Handle variable sized types.

  // FIXME: If we have a volatile struct, the optimizer can remove what might
  // appear to be `extra' memory ops:
  //
  // volatile struct { int i; } a, b;
  //
  // int main() {
  //   a = b;
  //   a = b;
  // }
  //
  // we need to use a different call here.  We use isVolatile to indicate when
  // either the source or the destination is volatile.

  llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
  llvm::Type *DBP =
    llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace());
  DestPtr = Builder.CreateBitCast(DestPtr, DBP);

  llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
  llvm::Type *SBP =
    llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace());
  SrcPtr = Builder.CreateBitCast(SrcPtr, SBP);

  // Don't do any of the memmove_collectable tests if GC isn't set.
  if (CGM.getLangOptions().getGC() == LangOptions::NonGC) {
    // fall through
  } else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
    RecordDecl *Record = RecordTy->getDecl();
    if (Record->hasObjectMember()) {
      CharUnits size = TypeInfo.first;
      llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
      llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity());
      CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 
                                                    SizeVal);
      return;
    }
  } else if (Ty->isArrayType()) {
    QualType BaseType = getContext().getBaseElementType(Ty);
    if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
      if (RecordTy->getDecl()->hasObjectMember()) {
        CharUnits size = TypeInfo.first;
        llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
        llvm::Value *SizeVal = 
          llvm::ConstantInt::get(SizeTy, size.getQuantity());
        CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 
                                                      SizeVal);
        return;
      }
    }
  }
  
  Builder.CreateMemCpy(DestPtr, SrcPtr,
                       llvm::ConstantInt::get(IntPtrTy, 
                                              TypeInfo.first.getQuantity()),
                       Alignment, isVolatile);
}
Пример #19
0
	string GetQName()const{ return decl ? decl->getQualifiedNameAsString() : ""; }
Пример #20
0
	string GetName()const{ return decl ? decl->getNameAsString() : ""; }
Пример #21
0
/// CreateType - get structure or union type.
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
                                     llvm::DICompileUnit Unit) {
  RecordDecl *Decl = Ty->getDecl();
  
  unsigned Tag;
  if (Decl->isStruct())
    Tag = llvm::dwarf::DW_TAG_structure_type;
  else if (Decl->isUnion())
    Tag = llvm::dwarf::DW_TAG_union_type;
  else {
    assert(Decl->isClass() && "Unknown RecordType!");
    Tag = llvm::dwarf::DW_TAG_class_type;
  }

  SourceManager &SM = M->getContext().getSourceManager();

  // Get overall information about the record type for the debug info.
  std::string Name = Decl->getNameAsString();

  llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(Decl->getLocation());
  unsigned Line = SM.getInstantiationLineNumber(Decl->getLocation());
  
  
  // Records and classes and unions can all be recursive.  To handle them, we
  // first generate a debug descriptor for the struct as a forward declaration.
  // Then (if it is a definition) we go through and get debug info for all of
  // its members.  Finally, we create a descriptor for the complete type (which
  // may refer to the forward decl if the struct is recursive) and replace all
  // uses of the forward declaration with the final definition.
  llvm::DIType FwdDecl =
    DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, 0, 0, 0, 0,
                                     llvm::DIType(), llvm::DIArray());
  
  // If this is just a forward declaration, return it.
  if (!Decl->getDefinition(M->getContext()))
    return FwdDecl;

  // Otherwise, insert it into the TypeCache so that recursive uses will find
  // it.
  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;

  // Convert all the elements.
  llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;

  const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(Decl);

  unsigned FieldNo = 0;
  for (RecordDecl::field_iterator I = Decl->field_begin(M->getContext()),
                                  E = Decl->field_end(M->getContext()); 
       I != E; ++I, ++FieldNo) {
    FieldDecl *Field = *I;
    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);

    std::string FieldName = Field->getNameAsString();

    // Get the location for the field.
    SourceLocation FieldDefLoc = Field->getLocation();
    llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
    unsigned FieldLine = SM.getInstantiationLineNumber(FieldDefLoc);

    QualType FType = Field->getType();
    uint64_t FieldSize = 0;
    unsigned FieldAlign = 0;
    if (!FType->isIncompleteArrayType()) {
    
      // Bit size, align and offset of the type.
      FieldSize = M->getContext().getTypeSize(FType);
      Expr *BitWidth = Field->getBitWidth();
      if (BitWidth)
        FieldSize = 
          BitWidth->getIntegerConstantExprValue(M->getContext()).getZExtValue();
      
      FieldAlign =  M->getContext().getTypeAlign(FType);
    }

    uint64_t FieldOffset = RL.getFieldOffset(FieldNo);    
    
    // Create a DW_TAG_member node to remember the offset of this field in the
    // struct.  FIXME: This is an absolutely insane way to capture this
    // information.  When we gut debug info, this should be fixed.
    FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
                                             FieldName, FieldDefUnit,
                                             FieldLine, FieldSize, FieldAlign,
                                             FieldOffset, 0, FieldTy);
    EltTys.push_back(FieldTy);
  }
  
  llvm::DIArray Elements =
    DebugFactory.GetOrCreateArray(&EltTys[0], EltTys.size());

  // Bit size, align and offset of the type.
  uint64_t Size = M->getContext().getTypeSize(Ty);
  uint64_t Align = M->getContext().getTypeAlign(Ty);
  
  llvm::DIType RealDecl =
    DebugFactory.CreateCompositeType(Tag, Unit, Name, DefUnit, Line, Size,
                                     Align, 0, 0, llvm::DIType(), Elements);

  // Now that we have a real decl for the struct, replace anything using the
  // old decl with the new one.  This will recursively update the debug info.
  FwdDecl.getGV()->replaceAllUsesWith(RealDecl.getGV());
  FwdDecl.getGV()->eraseFromParent();
  
  return RealDecl;
}
Пример #22
0
 bool GetRecordTypeFromDecl(RecordDecl * rd, Obj * tt) {
     if(rd->isStruct() || rd->isUnion()) {
         std::string name = rd->getName();
         Obj * thenamespace = &tagged;
         if(name == "") {
             TypedefNameDecl * decl = rd->getTypedefNameForAnonDecl();
             if(decl) {
                 thenamespace = &general;
                 name = decl->getName();
             }
         }
         //if name == "" then we have an anonymous struct
         if(!thenamespace->obj(name.c_str(),tt)) {
             PushTypeField("getorcreatecstruct");
             lua_pushstring(L, name.c_str());
             lua_pushboolean(L, thenamespace == &tagged);
             lua_call(L,2,1);
             tt->initFromStack(L,ref_table);
             if(!tt->boolean("llvm_definingfunction")) {
                 std::string definingfunction;
                 size_t argpos;
                 RegisterRecordType(Context->getRecordType(rd), &definingfunction, &argpos);
                 lua_pushstring(L,definingfunction.c_str());
                 tt->setfield("llvm_definingfunction");
                 lua_pushinteger(L,argpos);
                 tt->setfield("llvm_argumentposition");
             }
             if(name != "") { //do not remember a name for an anonymous struct
                 tt->push();
                 thenamespace->setfield(name.c_str()); //register the type
             }
         }
         
         if(tt->boolean("undefined") && rd->getDefinition() != NULL) {
             tt->clearfield("undefined");
             RecordDecl * defn = rd->getDefinition();
             Obj entries;
             tt->newlist(&entries);
             if(GetFields(defn, &entries)) {
                 if(!defn->isUnion()) {
                     //structtype.entries = {entry1, entry2, ... }
                     entries.push();
                     tt->setfield("entries");
                 } else {
                     //add as a union:
                     //structtype.entries = { {entry1,entry2,...} }
                     Obj allentries;
                     tt->obj("entries",&allentries);
                     entries.push();
                     allentries.addentry();
                 }
                 tt->pushfield("complete");
                 tt->push();
                 lua_call(L,1,0);
             }
         }
         
         return true;
     } else {
         return ImportError("non-struct record types are not supported");
     }
 }
Пример #23
0
    bool GetRecordTypeFromDecl(RecordDecl * rd, Obj * tt, std::string * fullname) {
        if(rd->isStruct() || rd->isUnion()) {
            std::string name = rd->getName();
            //TODO: why do some types not have names?
            Obj * thenamespace = &tagged;
            if(name == "") {
                TypedefNameDecl * decl = rd->getTypedefNameForAnonDecl();
                if(decl) {
                    thenamespace = &general;
                    name = decl->getName();
                } else {
                    name = "anon";
                }
            }

            assert(name != "");

            if(!thenamespace->obj(name.c_str(),tt)) {
                //create new blank struct, fill in with members
                std::stringstream ss;
                ss << (rd->isStruct() ? "struct." : "union.") << name;
                PushTypeFunction("getorcreatecstruct");
                lua_pushstring(L, name.c_str());
                lua_pushstring(L,ss.str().c_str());
                lua_call(L,2,1);
                tt->initFromStack(L,ref_table);
                tt->push();
                thenamespace->setfield(name.c_str()); //register the type (this prevents an infinite loop for recursive types)
            }
            
            if(tt->boolean("undefined") && rd->getDefinition() != NULL) {
                tt->clearfield("undefined");
                RecordDecl * defn = rd->getDefinition();
                Obj entries;
                tt->newlist(&entries);
                if(GetFields(defn, &entries)) {
                    if(!defn->isUnion()) {
                        //structtype.entries = {entry1, entry2, ... }
                        entries.push();
                        tt->setfield("entries");
                    } else {
                        //add as a union:
                        //structtype.entries = { {entry1,entry2,...} }
                        Obj allentries;
                        tt->obj("entries",&allentries);
                        entries.push();
                        allentries.addentry();
                    }
                    tt->pushfield("complete");
                    tt->push();
                    lua_call(L,1,0);
                }
            }
            
            if(fullname) {
                std::stringstream ss;
                if(thenamespace == &tagged)
                    ss << (rd->isStruct() ? "struct " : "union ");
                ss << name;
                *fullname = ss.str();
            }
            
            return true;
        } else {
            return ImportError("non-struct record types are not supported");
        }
    }