diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 | 
| commit | 73490b890977362d28dd6326843a1ecae413921d (patch) | |
| tree | 3fdd91eae574e32453a4baf462961c742df2691a /lib/CodeGen | |
| parent | a5f348eb914e67b51914117fac117c18c1f8d650 (diff) | |
Diffstat (limited to 'lib/CodeGen')
| -rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 140 | ||||
| -rw-r--r-- | lib/CodeGen/CGBlocks.h | 20 | ||||
| -rw-r--r-- | lib/CodeGen/CGCXX.cpp | 15 | ||||
| -rw-r--r-- | lib/CodeGen/CGCall.cpp | 5 | ||||
| -rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 99 | ||||
| -rw-r--r-- | lib/CodeGen/CGDebugInfo.h | 2 | ||||
| -rw-r--r-- | lib/CodeGen/CGDecl.cpp | 5 | ||||
| -rw-r--r-- | lib/CodeGen/CGExpr.cpp | 121 | ||||
| -rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 25 | ||||
| -rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 6 | ||||
| -rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 256 | ||||
| -rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 199 | ||||
| -rw-r--r-- | lib/CodeGen/CGVtable.cpp | 71 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 6 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 11 | ||||
| -rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 8 | ||||
| -rw-r--r-- | lib/CodeGen/Mangle.cpp | 14 | ||||
| -rw-r--r-- | lib/CodeGen/TargetABIInfo.cpp | 20 | 
18 files changed, 693 insertions, 330 deletions
| diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 736425e01276..682cf5da1e72 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -73,29 +73,60 @@ llvm::Constant *BlockModule::getNSConcreteStackBlock() {    return NSConcreteStackBlock;  } -static void CollectBlockDeclRefInfo(const Stmt *S, -                                    CodeGenFunction::BlockInfo &Info) { +static void CollectBlockDeclRefInfo( +  const Stmt *S, CodeGenFunction::BlockInfo &Info, +  llvm::SmallSet<const DeclContext *, 16> &InnerContexts) {    for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();         I != E; ++I)      if (*I) -      CollectBlockDeclRefInfo(*I, Info); +      CollectBlockDeclRefInfo(*I, Info, InnerContexts); -  if (const BlockDeclRefExpr *DE = dyn_cast<BlockDeclRefExpr>(S)) { +  // We want to ensure we walk down into block literals so we can find +  // all nested BlockDeclRefExprs. +  if (const BlockExpr *BE = dyn_cast<BlockExpr>(S)) { +    InnerContexts.insert(cast<DeclContext>(BE->getBlockDecl())); +    CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts); +  } + +  if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {      // FIXME: Handle enums. -    if (isa<FunctionDecl>(DE->getDecl())) +    if (isa<FunctionDecl>(BDRE->getDecl()))        return; -    if (DE->isByRef()) -      Info.ByRefDeclRefs.push_back(DE); -    else -      Info.ByCopyDeclRefs.push_back(DE); +    // Only Decls that escape are added. +    if (!InnerContexts.count(BDRE->getDecl()->getDeclContext())) +      Info.DeclRefs.push_back(BDRE);    }  }  /// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be  /// declared as a global variable instead of on the stack.  static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) { -  return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty(); +  return Info.DeclRefs.empty(); +} + +/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to +/// ensure we can generate the debug information for the parameter for the block +/// invoke function. +static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info, +                                     CodeGenFunction *CGF) { +  // Always allocate self, as it is often handy in the debugger, even if there +  // is no codegen in the block that uses it.  This is also useful to always do +  // this as if we didn't, we'd have to figure out all code that uses a self +  // pointer, including implicit uses. +  if (const ObjCMethodDecl *OMD +      = dyn_cast_or_null<ObjCMethodDecl>(CGF->CurFuncDecl)) { +    ImplicitParamDecl *SelfDecl = OMD->getSelfDecl(); +    BlockDeclRefExpr *BDRE = new (CGF->getContext()) +      BlockDeclRefExpr(SelfDecl, +                       SelfDecl->getType(), SourceLocation(), false); +    CGF->AllocateBlockDecl(BDRE); +  } + +  // FIXME: Also always forward the this pointer in C++ as well. + +  for (size_t i = 0; i < Info.DeclRefs.size(); ++i) +    CGF->AllocateBlockDecl(Info.DeclRefs[i]);  }  // FIXME: Push most into CGM, passing down a few bits, like current function @@ -104,7 +135,9 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {    std::string Name = CurFn->getName();    CodeGenFunction::BlockInfo Info(0, Name.c_str()); -  CollectBlockDeclRefInfo(BE->getBody(), Info); +  llvm::SmallSet<const DeclContext *, 16> InnerContexts; +  InnerContexts.insert(BE->getBlockDecl()); +  CollectBlockDeclRefInfo(BE->getBody(), Info, InnerContexts);    // Check if the block can be global.    // FIXME: This test doesn't work for nested blocks yet.  Longer term, I'd like @@ -159,7 +192,8 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {      if (subBlockDeclRefDecls.size() == 0) {        // __descriptor -      Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0); +      Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, +                                         0, 0);        // Optimize to being a global block.        Elts[0] = CGM.getNSConcreteGlobalBlock(); @@ -269,7 +303,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {              llvm::Value *BlockLiteral = LoadBlockStruct();              Loc = Builder.CreateGEP(BlockLiteral, -                                    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), +                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),                                                             offset),                                      "block.literal");              Ty = llvm::PointerType::get(Ty, 0); @@ -391,10 +425,6 @@ const llvm::Type *BlockModule::getGenericExtendedBlockLiteralType() {    return GenericExtendedBlockLiteralType;  } -bool BlockFunction::BlockRequiresCopying(QualType Ty) { -  return CGM.BlockRequiresCopying(Ty); -} -  RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {    const BlockPointerType *BPT =      E->getCallee()->getType()->getAs<BlockPointerType>(); @@ -447,24 +477,34 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {    return EmitCall(FnInfo, Func, Args);  } -llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { +uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {    const ValueDecl *VD = E->getDecl(); -      uint64_t &offset = BlockDecls[VD]; -    // See if we have already allocated an offset for this variable. -  if (offset == 0) { -    // Don't run the expensive check, unless we have to. -    if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType())) +  if (offset) +    return offset; + +  // Don't run the expensive check, unless we have to. +  if (!BlockHasCopyDispose) +    if (E->isByRef() +        || BlockRequiresCopying(E->getType()))        BlockHasCopyDispose = true; -    // if not, allocate one now. -    offset = getBlockOffset(E); -  } + +  // if not, allocate one now. +  offset = getBlockOffset(E); + +  return offset; +} + +llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) { +  const ValueDecl *VD = E->getDecl(); +  uint64_t offset = AllocateBlockDecl(E); +      llvm::Value *BlockLiteral = LoadBlockStruct();    llvm::Value *V = Builder.CreateGEP(BlockLiteral, -                                  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), +                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),                                                           offset),                                       "block.literal");    if (E->isByRef()) { @@ -576,7 +616,10 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {  }  llvm::Value *CodeGenFunction::LoadBlockStruct() { -  return Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()], "self"); +  llvm::Value *V = Builder.CreateLoad(LocalDeclMap[getBlockStructDecl()], +                                      "self"); +  // For now, we codegen based upon byte offsets. +  return Builder.CreateBitCast(V, PtrToInt8Ty);  }  llvm::Function * @@ -605,14 +648,8 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,        LocalDeclMap[VD] = i->second;    } -  // FIXME: We need to rearrange the code for copy/dispose so we have this -  // sooner, so we can calculate offsets correctly. -  if (!BlockHasCopyDispose) -    BlockOffset = CGM.getTargetData() -      .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8; -  else -    BlockOffset = CGM.getTargetData() -      .getTypeStoreSizeInBits(CGM.getGenericExtendedBlockLiteralType()) / 8; +  BlockOffset = CGM.getTargetData() +    .getTypeStoreSizeInBits(CGM.getGenericBlockLiteralType()) / 8;    BlockAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8;    const FunctionType *BlockFunctionType = BExpr->getFunctionType(); @@ -630,13 +667,22 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,    FunctionArgList Args; +  CurFuncDecl = OuterFuncDecl; +    const BlockDecl *BD = BExpr->getBlockDecl(); +  IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor"); + +  // Allocate all BlockDeclRefDecls, so we can calculate the right ParmTy below. +  AllocateAllBlockDeclRefs(Info, this); + +  QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose, +                                                  BlockDeclRefDecls);    // FIXME: This leaks    ImplicitParamDecl *SelfDecl =      ImplicitParamDecl::Create(getContext(), 0, -                              SourceLocation(), 0, -                              getContext().getPointerType(getContext().VoidTy)); +                              SourceLocation(), II, +                              ParmTy);    Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));    BlockStructDecl = SelfDecl; @@ -758,11 +804,13 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T,    FunctionArgList Args;    // FIXME: This leaks    ImplicitParamDecl *Dst = -    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, +    ImplicitParamDecl::Create(getContext(), 0, +                              SourceLocation(), 0,                                getContext().getPointerType(getContext().VoidTy));    Args.push_back(std::make_pair(Dst, Dst->getType()));    ImplicitParamDecl *Src = -    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, +    ImplicitParamDecl::Create(getContext(), 0, +                              SourceLocation(), 0,                                getContext().getPointerType(getContext().VoidTy));    Args.push_back(std::make_pair(Src, Src->getType())); @@ -843,7 +891,8 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose,    FunctionArgList Args;    // FIXME: This leaks    ImplicitParamDecl *Src = -    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, +    ImplicitParamDecl::Create(getContext(), 0, +                              SourceLocation(), 0,                                getContext().getPointerType(getContext().VoidTy));    Args.push_back(std::make_pair(Src, Src->getType())); @@ -922,13 +971,15 @@ GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) {    FunctionArgList Args;    // FIXME: This leaks    ImplicitParamDecl *Dst = -    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, +    ImplicitParamDecl::Create(getContext(), 0, +                              SourceLocation(), 0,                                getContext().getPointerType(getContext().VoidTy));    Args.push_back(std::make_pair(Dst, Dst->getType()));    // FIXME: This leaks    ImplicitParamDecl *Src = -    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, +    ImplicitParamDecl::Create(getContext(), 0, +                              SourceLocation(), 0,                                getContext().getPointerType(getContext().VoidTy));    Args.push_back(std::make_pair(Src, Src->getType())); @@ -991,7 +1042,8 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T,    FunctionArgList Args;    // FIXME: This leaks    ImplicitParamDecl *Src = -    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0, +    ImplicitParamDecl::Create(getContext(), 0, +                              SourceLocation(), 0,                                getContext().getPointerType(getContext().VoidTy));    Args.push_back(std::make_pair(Src, Src->getType())); diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 3a860c0d3c36..3ab4efb71bee 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -115,15 +115,8 @@ public:      PtrToInt8Ty = llvm::Type::getInt8PtrTy(M.getContext());    } -  bool BlockRequiresCopying(QualType Ty) { -    if (Ty->isBlockPointerType()) -      return true; -    if (getContext().isObjCNSObjectType(Ty)) -      return true; -    if (Ty->isObjCObjectPointerType()) -      return true; -    return false; -  } +  bool BlockRequiresCopying(QualType Ty) +    { return getContext().BlockRequiresCopying(Ty); }  };  class BlockFunction : public BlockBase { @@ -165,11 +158,7 @@ public:      /// ByCopyDeclRefs - Variables from parent scopes that have been imported      /// into this block. -    llvm::SmallVector<const BlockDeclRefExpr *, 8> ByCopyDeclRefs; - -    // ByRefDeclRefs - __block variables from parent scopes that have been -    // imported into this block. -    llvm::SmallVector<const BlockDeclRefExpr *, 8> ByRefDeclRefs; +    llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;      BlockInfo(const llvm::Type *blt, const char *n)        : BlockLiteralTy(blt), Name(n) { @@ -228,7 +217,8 @@ public:    llvm::Value *getBlockObjectDispose();    void BuildBlockRelease(llvm::Value *DeclPtr, int flag = BLOCK_FIELD_IS_BYREF); -  bool BlockRequiresCopying(QualType Ty); +  bool BlockRequiresCopying(QualType Ty) +    { return getContext().BlockRequiresCopying(Ty); }  };  }  // end namespace CodeGen diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 3960cf51868f..cfa669dc4b6e 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -590,12 +590,15 @@ void  CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,                                        const CXXConstructExpr *E) {    assert(Dest && "Must have a destination!"); - -  const CXXRecordDecl *RD = -  cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); -  if (RD->hasTrivialConstructor()) +  const CXXConstructorDecl *CD = E->getConstructor(); +  // For a copy constructor, even if it is trivial, must fall thru so +  // its argument is code-gen'ed. +  if (!CD->isCopyConstructor(getContext())) { +    const CXXRecordDecl *RD = +      cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl()); +    if (RD->hasTrivialConstructor())      return; - +  }    // Code gen optimization to eliminate copy constructor and return    // its first argument instead.    if (getContext().getLangOptions().ElideConstructors && E->isElidable()) { @@ -604,7 +607,7 @@ CodeGenFunction::EmitCXXConstructExpr(llvm::Value *Dest,      return;    }    // Call the constructor. -  EmitCXXConstructorCall(E->getConstructor(), Ctor_Complete, Dest, +  EmitCXXConstructorCall(CD, Ctor_Complete, Dest,                           E->arg_begin(), E->arg_end());  } diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index bad166f01ef5..78655168e857 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -639,9 +639,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,        // If this structure was expanded into multiple arguments then        // we need to create a temporary and reconstruct it from the        // arguments. -      std::string Name = Arg->getNameAsString();        llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(Ty), -                                           (Name + ".addr").c_str()); +                                           Arg->getName() + ".addr");        // FIXME: What are the right qualifiers here?        llvm::Function::arg_iterator End =          ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp, Qualifiers()), AI); @@ -650,7 +649,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,        // Name the arguments used in expansion and increment AI.        unsigned Index = 0;        for (; AI != End; ++AI, ++Index) -        AI->setName(Name + "." + llvm::Twine(Index)); +        AI->setName(Arg->getName() + "." + llvm::Twine(Index));        continue;      } diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 4c624205b4ca..1b01e1537b42 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -173,10 +173,14 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,    uint64_t Align = M->getContext().getTypeAlign(BT);    uint64_t Offset = 0; -  return DebugFactory.CreateBasicType(Unit, -                                  BT->getName(M->getContext().getLangOptions()), -                                      Unit, 0, Size, Align, -                                      Offset, /*flags*/ 0, Encoding); +  llvm::DIType DbgTy =  +    DebugFactory.CreateBasicType(Unit, +                                 BT->getName(M->getContext().getLangOptions()), +                                 Unit, 0, Size, Align, +                                 Offset, /*flags*/ 0, Encoding); + +  TypeCache[QualType(BT, 0).getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  }  llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty, @@ -190,9 +194,12 @@ llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty,    uint64_t Align = M->getContext().getTypeAlign(Ty);    uint64_t Offset = 0; -  return DebugFactory.CreateBasicType(Unit, "complex", -                                      Unit, 0, Size, Align, -                                      Offset, /*flags*/ 0, Encoding); +  llvm::DIType DbgTy =  +    DebugFactory.CreateBasicType(Unit, "complex", +                                 Unit, 0, Size, Align, +                                 Offset, /*flags*/ 0, Encoding); +  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  }  /// CreateCVRType - Get the qualified type from the cache or create @@ -226,8 +233,11 @@ llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DICompileUnit U    // No need to fill in the Name, Line, Size, Alignment, Offset in case of    // CVR derived types. -  return DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(), -                                        0, 0, 0, 0, 0, FromTy); +  llvm::DIType DbgTy = +    DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(), +                                   0, 0, 0, 0, 0, FromTy); +  TypeCache[Ty.getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  }  llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty, @@ -238,9 +248,12 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,    uint64_t Size = M->getContext().getTypeSize(Ty);    uint64_t Align = M->getContext().getTypeAlign(Ty); -  return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit, -                                        "", llvm::DICompileUnit(), -                                        0, Size, Align, 0, 0, EltTy); +  llvm::DIType DbgTy = +    DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit, +                                   "", llvm::DICompileUnit(), +                                   0, Size, Align, 0, 0, EltTy); +  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  }  llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty, @@ -251,9 +264,10 @@ llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,    uint64_t Size = M->getContext().getTypeSize(Ty);    uint64_t Align = M->getContext().getTypeAlign(Ty); -  return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit, -                                        "", llvm::DICompileUnit(), -                                        0, Size, Align, 0, 0, EltTy); +  return +    DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit, +                                   "", llvm::DICompileUnit(), +                                   0, Size, Align, 0, 0, EltTy);  }  llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, @@ -401,8 +415,11 @@ llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,    PresumedLoc PLoc = SM.getPresumedLoc(DefLoc);    unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine(); -  return DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_typedef, Unit, -                                        TyName, DefUnit, Line, 0, 0, 0, 0, Src); +  llvm::DIType DbgTy =  +    DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_typedef, Unit, +                                   TyName, DefUnit, Line, 0, 0, 0, 0, Src); +  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  }  llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, @@ -424,10 +441,13 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,    llvm::DIArray EltTypeArray =      DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size()); -  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, -                                          Unit, "", llvm::DICompileUnit(), -                                          0, 0, 0, 0, 0, -                                          llvm::DIType(), EltTypeArray); +  llvm::DIType DbgTy = +    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type, +                                     Unit, "", llvm::DICompileUnit(), +                                     0, 0, 0, 0, 0, +                                     llvm::DIType(), EltTypeArray); +  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  }  /// CreateType - get structure or union type. @@ -713,10 +733,14 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,      Align = M->getContext().getTypeAlign(Ty);    } -  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type, -                                          Unit, EnumName, DefUnit, Line, -                                          Size, Align, 0, 0, -                                          llvm::DIType(), EltArray); +  llvm::DIType DbgTy =  +    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_enumeration_type, +                                     Unit, EnumName, DefUnit, Line, +                                     Size, Align, 0, 0, +                                     llvm::DIType(), EltArray); +   +  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  }  llvm::DIType CGDebugInfo::CreateType(const TagType *Ty, @@ -767,11 +791,15 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,    llvm::DIArray SubscriptArray =      DebugFactory.GetOrCreateArray(Subscripts.data(), Subscripts.size()); -  return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type, -                                          Unit, "", llvm::DICompileUnit(), -                                          0, Size, Align, 0, 0, -                                          getOrCreateType(EltTy, Unit), -                                          SubscriptArray); +  llvm::DIType DbgTy =  +    DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type, +                                     Unit, "", llvm::DICompileUnit(), +                                     0, Size, Align, 0, 0, +                                     getOrCreateType(EltTy, Unit), +                                     SubscriptArray); +   +  TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = DbgTy.getNode(); +  return DbgTy;  } @@ -793,7 +821,6 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,    // Otherwise create the type.    llvm::DIType Res = CreateTypeNode(Ty, Unit); -  TypeCache.insert(std::make_pair(Ty.getAsOpaquePtr(), Res.getNode()));    return Res;  } @@ -846,8 +873,6 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,                             Unit);    case Type::ConstantArray: -  case Type::ConstantArrayWithExpr: -  case Type::ConstantArrayWithoutExpr:    case Type::VariableArray:    case Type::IncompleteArray:      return CreateType(cast<ArrayType>(Ty), Unit); @@ -863,7 +888,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,  /// EmitFunctionStart - Constructs the debug code for entering a function -  /// "llvm.dbg.func.start.". -void CGDebugInfo::EmitFunctionStart(const char *Name, QualType ReturnType, +void CGDebugInfo::EmitFunctionStart(const char *Name, QualType FnType,                                      llvm::Function *Fn,                                      CGBuilderTy &Builder) {    const char *LinkageName = Name; @@ -881,7 +906,7 @@ void CGDebugInfo::EmitFunctionStart(const char *Name, QualType ReturnType,    llvm::DISubprogram SP =      DebugFactory.CreateSubprogram(Unit, Name, Name, LinkageName, Unit, LineNo, -                                  getOrCreateType(ReturnType, Unit), +                                  getOrCreateType(FnType, Unit),                                    Fn->hasInternalLinkage(), true/*definition*/);  #ifndef ATTACH_DEBUG_INFO_TO_AN_INSN @@ -1366,7 +1391,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,    }    DebugFactory.CreateGlobalVariable(getContext(Decl, Unit),  -                                    Name, Name, "", Unit, LineNo, +                                    Name, Name, Name, Unit, LineNo,                                      getOrCreateType(T, Unit),                                      Var->hasInternalLinkage(),                                      true/*definition*/, Var); @@ -1396,7 +1421,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,                                             ArrayType::Normal, 0);    } -  DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo, +  DebugFactory.CreateGlobalVariable(Unit, Name, Name, Name, Unit, LineNo,                                      getOrCreateType(T, Unit),                                      Var->hasInternalLinkage(),                                      true/*definition*/, Var); diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index 0a617b999240..2e44e09d2590 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -88,7 +88,7 @@ public:    /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate    /// start of a new function. -  void EmitFunctionStart(const char *Name, QualType ReturnType, +  void EmitFunctionStart(const char *Name, QualType FnType,                           llvm::Function *Fn, CGBuilderTy &Builder);    /// EmitRegionStart - Emit a call to llvm.dbg.region.start to indicate start diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 7feff83dee6b..1728c67292b7 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -37,6 +37,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {    case Decl::Enum:      // enum X;    case Decl::EnumConstant: // enum ? { X = ? }    case Decl::CXXRecord: // struct/union/class X; [C++] +  case Decl::UsingDirective: // using X; [C++]      // None of these decls require codegen support.      return; @@ -275,8 +276,8 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const ValueDecl *D) {      unsigned NumPaddingBytes = AlignedOffsetInBytes - CurrentOffsetInBytes;      if (NumPaddingBytes > 0) {        const llvm::Type *Ty = llvm::Type::getInt8Ty(VMContext); -      // FIXME: We need a sema error for alignment larger than the minimum of the -      // maximal stack alignmint and the alignment of malloc on the system. +      // FIXME: We need a sema error for alignment larger than the minimum of +      // the maximal stack alignmint and the alignment of malloc on the system.        if (NumPaddingBytes > 1)          Ty = llvm::ArrayType::get(Ty, NumPaddingBytes); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 01a057f67455..bb487f6e3fdf 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -28,9 +28,9 @@ using namespace CodeGen;  /// CreateTempAlloca - This creates a alloca and inserts it into the entry  /// block.  llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty, -                                                    const char *Name) { +                                                    const llvm::Twine &Name) {    if (!Builder.isNamePreserving()) -    Name = ""; +    return new llvm::AllocaInst(Ty, 0, "", AllocaInsertPt);    return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);  } @@ -78,24 +78,18 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,  RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,                                                     QualType DestType,                                                     bool IsInitializer) { +  bool ShouldDestroyTemporaries = false; +  unsigned OldNumLiveTemporaries = 0; +      if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) { -    // If we shouldn't destroy the temporaries, just emit the -    // child expression. -    if (!TE->shouldDestroyTemporaries()) -      return EmitReferenceBindingToExpr(TE->getSubExpr(), DestType, -                                        IsInitializer); -     -    // Keep track of the current cleanup stack depth. -    unsigned OldNumLiveTemporaries = LiveTemporaries.size(); -     -    RValue RV = EmitReferenceBindingToExpr(TE->getSubExpr(), DestType, -                                           IsInitializer); -     -    // Pop temporaries. -    while (LiveTemporaries.size() > OldNumLiveTemporaries) -      PopCXXTemporary(); +    ShouldDestroyTemporaries = TE->shouldDestroyTemporaries(); + +    if (ShouldDestroyTemporaries) { +      // Keep track of the current cleanup stack depth. +      OldNumLiveTemporaries = LiveTemporaries.size(); +    } -    return RV; +    E = TE->getSubExpr();    }    RValue Val; @@ -105,6 +99,12 @@ RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,      if (LV.isSimple())        return RValue::get(LV.getAddress());      Val = EmitLoadOfLValue(LV, E->getType()); +     +    if (ShouldDestroyTemporaries) { +      // Pop temporaries. +      while (LiveTemporaries.size() > OldNumLiveTemporaries) +        PopCXXTemporary(); +    }          } else {      const CXXRecordDecl *BaseClassDecl = 0;      const CXXRecordDecl *DerivedClassDecl = 0; @@ -124,6 +124,12 @@ RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,      Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false,                              IsInitializer); +    if (ShouldDestroyTemporaries) { +      // Pop temporaries. +      while (LiveTemporaries.size() > OldNumLiveTemporaries) +        PopCXXTemporary(); +    }       +          if (IsInitializer) {        // We might have to destroy the temporary variable.        if (const RecordType *RT = E->getType()->getAs<RecordType>()) { @@ -297,6 +303,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {    case Expr::CXXReinterpretCastExprClass:    case Expr::CXXConstCastExprClass:      return EmitCastLValue(cast<CastExpr>(E)); +  case Expr::CXXZeroInitValueExprClass: +    return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E));    }  } @@ -858,6 +866,9 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {      llvm::Value *V = LocalDeclMap[IPD];      assert(V && "BlockVarDecl not entered in LocalDeclMap?");      return LValue::MakeAddr(V, MakeQualifiers(E->getType())); +  } else if (const QualifiedDeclRefExpr *QDRExpr =  +             dyn_cast<QualifiedDeclRefExpr>(E)) { +    return EmitPointerToDataMemberLValue(QDRExpr);    }    assert(0 && "Unimp declref");    //an invalid LValue, but the assert will @@ -1307,6 +1318,18 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {    }  } +LValue CodeGenFunction::EmitNullInitializationLValue( +                                              const CXXZeroInitValueExpr *E) { +  QualType Ty = E->getType(); +  const llvm::Type *LTy = ConvertTypeForMem(Ty); +  llvm::AllocaInst *Alloc = CreateTempAlloca(LTy); +  unsigned Align = getContext().getTypeAlign(Ty)/8; +  Alloc->setAlignment(Align); +  LValue lvalue = LValue::MakeAddr(Alloc, Qualifiers()); +  EmitMemSetToZero(lvalue.getAddress(), Ty); +  return lvalue; +} +  //===--------------------------------------------------------------------===//  //                             Expression Emission  //===--------------------------------------------------------------------===// @@ -1356,11 +1379,24 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {      return EmitLValue(E->getRHS());    } +  if (E->getOpcode() == BinaryOperator::PtrMemD) +    return EmitPointerToDataMemberBinaryExpr(E); +      // Can only get l-value for binary operator expressions which are a    // simple assignment of aggregate type.    if (E->getOpcode() != BinaryOperator::Assign)      return EmitUnsupportedLValue(E, "binary l-value expression"); +  if (!hasAggregateLLVMType(E->getType())) { +    // Emit the LHS as an l-value. +    LValue LV = EmitLValue(E->getLHS()); +     +    llvm::Value *RHS = EmitScalarExpr(E->getRHS()); +    EmitStoreOfScalar(RHS, LV.getAddress(), LV.isVolatileQualified(),  +                      E->getType()); +    return LV; +  } +      llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType()));    EmitAggExpr(E, Temp, false);    // FIXME: Are these qualifiers correct? @@ -1483,6 +1519,25 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {  } +LValue CodeGenFunction::EmitPointerToDataMemberLValue( +                                              const QualifiedDeclRefExpr *E) { +  const FieldDecl *Field = cast<FieldDecl>(E->getDecl()); +  const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Field->getDeclContext()); +  QualType NNSpecTy =  +    getContext().getCanonicalType( +      getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(ClassDecl))); +  NNSpecTy = getContext().getPointerType(NNSpecTy); +  llvm::Value *V = llvm::Constant::getNullValue(ConvertType(NNSpecTy)); +  LValue MemExpLV = EmitLValueForField(V, const_cast<FieldDecl*>(Field),  +                                       /*isUnion*/false, /*Qualifiers*/0); +  const llvm::Type* ResultType = ConvertType( +                                             getContext().getPointerDiffType()); +  V = Builder.CreatePtrToInt(MemExpLV.getAddress(), ResultType,  +                             "datamember"); +  LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType())); +  return LV; +} +  RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType,                                   CallExpr::const_arg_iterator ArgBeg,                                   CallExpr::const_arg_iterator ArgEnd, @@ -1492,11 +1547,13 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType,    assert(CalleeType->isFunctionPointerType() &&           "Call must have function pointer type!"); -  QualType FnType = CalleeType->getAs<PointerType>()->getPointeeType(); -  QualType ResultType = FnType->getAs<FunctionType>()->getResultType(); +  CalleeType = getContext().getCanonicalType(CalleeType); + +  QualType FnType = cast<PointerType>(CalleeType)->getPointeeType(); +  QualType ResultType = cast<FunctionType>(FnType)->getResultType();    CallArgList Args; -  EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), ArgBeg, ArgEnd); +  EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);    // FIXME: We should not need to do this, it should be part of the function    // type. @@ -1508,3 +1565,25 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType,                                                   CallingConvention),                    Callee, Args, TargetDecl);  } + +LValue CodeGenFunction::EmitPointerToDataMemberBinaryExpr( +                                                    const BinaryOperator *E) { +  llvm::Value *BaseV = EmitLValue(E->getLHS()).getAddress(); +  const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(getLLVMContext()); +  BaseV = Builder.CreateBitCast(BaseV, i8Ty); +  LValue RHSLV = EmitLValue(E->getRHS()); +  llvm::Value *OffsetV =  +    EmitLoadOfLValue(RHSLV, E->getRHS()->getType()).getScalarVal(); +  const llvm::Type* ResultType = ConvertType(getContext().getPointerDiffType()); +  OffsetV = Builder.CreateBitCast(OffsetV, ResultType); +  llvm::Value *AddV = Builder.CreateInBoundsGEP(BaseV, OffsetV, "add.ptr"); +  QualType Ty = E->getRHS()->getType(); +  const MemberPointerType *MemPtrType = Ty->getAs<MemberPointerType>(); +  Ty = MemPtrType->getPointeeType(); +  const llvm::Type* PType =  +  ConvertType(getContext().getPointerType(Ty)); +  AddV = Builder.CreateBitCast(AddV, PType); +  LValue LV = LValue::MakeAddr(AddV, MakeQualifiers(Ty)); +  return LV; +} + diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 0866ff893c4e..f47b6ab3c8cc 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -92,6 +92,7 @@ public:    void VisitCallExpr(const CallExpr *E);    void VisitStmtExpr(const StmtExpr *E);    void VisitBinaryOperator(const BinaryOperator *BO); +  void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);    void VisitBinAssign(const BinaryOperator *E);    void VisitBinComma(const BinaryOperator *E);    void VisitUnaryAddrOf(const UnaryOperator *E); @@ -112,6 +113,7 @@ public:    void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);    void VisitCXXConstructExpr(const CXXConstructExpr *E);    void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E); +  void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);    void VisitVAArgExpr(VAArgExpr *E); @@ -214,6 +216,12 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {      break;    } +  case CastExpr::CK_BitCast: { +    // This must be a member function pointer cast. +    Visit(E->getSubExpr()); +    break; +  } +    case CastExpr::CK_BaseToDerivedMemberPointer: {      QualType SrcType = E->getSubExpr()->getType(); @@ -285,6 +293,7 @@ void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {  void AggExprEmitter::VisitUnaryAddrOf(const UnaryOperator *E) {    // We have a member function pointer.    const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>(); +  (void) MPT;    assert(MPT->getPointeeType()->isFunctionProtoType() &&           "Unexpected member pointer type!"); @@ -320,7 +329,16 @@ void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {  }  void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) { -  CGF.ErrorUnsupported(E, "aggregate binary expression"); +  if (E->getOpcode() == BinaryOperator::PtrMemD) +    VisitPointerToDataMemberBinaryOperator(E); +  else +    CGF.ErrorUnsupported(E, "aggregate binary expression"); +} + +void AggExprEmitter::VisitPointerToDataMemberBinaryOperator( +                                                    const BinaryOperator *E) { +  LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E); +  EmitFinalDestCopy(E, LV);  }  void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { @@ -438,6 +456,11 @@ void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {    CGF.EmitCXXExprWithTemporaries(E, DestPtr, VolatileDest, IsInitializer);  } +void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { +  LValue lvalue = LValue::MakeAddr(DestPtr, Qualifiers()); +  EmitNullInitializationToLValue(lvalue, E->getType()); +} +  void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {    // FIXME: Ignore result?    // FIXME: Are initializers affected by volatile? diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 7f540c3c0688..fc3748c8e3c8 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -542,7 +542,11 @@ public:          return CS;        }                } -         + +    case CastExpr::CK_BitCast:  +      // This must be a member function pointer cast. +      return Visit(E->getSubExpr()); +      default: {        // FIXME: This should be handled by the CK_NoOp cast kind.        // Explicit and implicit no-op casts diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index cc81256032af..69604f9aaaee 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -106,6 +106,7 @@ public:      return 0;    }    Value *VisitExpr(Expr *S); +      Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); }    // Leaves. @@ -181,48 +182,7 @@ public:    Value *VisitPredefinedExpr(Expr *E) { return EmitLValue(E).getAddress(); } -  Value *VisitInitListExpr(InitListExpr *E) { -    bool Ignore = TestAndClearIgnoreResultAssign(); -    (void)Ignore; -    assert (Ignore == false && "init list ignored"); -    unsigned NumInitElements = E->getNumInits(); - -    if (E->hadArrayRangeDesignator()) { -      CGF.ErrorUnsupported(E, "GNU array range designator extension"); -    } - -    const llvm::VectorType *VType = -      dyn_cast<llvm::VectorType>(ConvertType(E->getType())); - -    // We have a scalar in braces. Just use the first element. -    if (!VType) -      return Visit(E->getInit(0)); - -    unsigned NumVectorElements = VType->getNumElements(); -    const llvm::Type *ElementType = VType->getElementType(); - -    // Emit individual vector element stores. -    llvm::Value *V = llvm::UndefValue::get(VType); - -    // Emit initializers -    unsigned i; -    for (i = 0; i < NumInitElements; ++i) { -      Value *NewV = Visit(E->getInit(i)); -      Value *Idx = -        llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()), i); -      V = Builder.CreateInsertElement(V, NewV, Idx); -    } - -    // Emit remaining default initializers -    for (/* Do not initialize i*/; i < NumVectorElements; ++i) { -      Value *Idx = -        llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()), i); -      llvm::Value *NewV = llvm::Constant::getNullValue(ElementType); -      V = Builder.CreateInsertElement(V, NewV, Idx); -    } - -    return V; -  } +  Value *VisitInitListExpr(InitListExpr *E);    Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {      return llvm::Constant::getNullValue(ConvertType(E->getType())); @@ -404,7 +364,7 @@ public:  /// EmitConversionToBool - Convert the specified expression value to a  /// boolean (i1) truth value.  This is equivalent to "Val != 0".  Value *ScalarExprEmitter::EmitConversionToBool(Value *Src, QualType SrcType) { -  assert(SrcType->isCanonical() && "EmitScalarConversion strips typedefs"); +  assert(SrcType.isCanonical() && "EmitScalarConversion strips typedefs");    if (SrcType->isRealFloatingType()) {      // Compare against 0.0 for fp scalars. @@ -577,6 +537,13 @@ EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,  //===----------------------------------------------------------------------===//  Value *ScalarExprEmitter::VisitExpr(Expr *E) { +  if (const BinaryOperator *BExpr = dyn_cast<BinaryOperator>(E)) +    if (BExpr->getOpcode() == BinaryOperator::PtrMemD) { +      LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(BExpr); +      Value *InVal = CGF.EmitLoadOfLValue(LV, E->getType()).getScalarVal(); +      return InVal; +    } +      CGF.ErrorUnsupported(E, "scalar expression");    if (E->getType()->isVoidType())      return 0; @@ -616,6 +583,174 @@ Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {    return Builder.CreateExtractElement(Base, Idx, "vecext");  } +static llvm::Constant *getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, +                                  unsigned Off, const llvm::Type *I32Ty) { +  int MV = SVI->getMaskValue(Idx); +  if (MV == -1)  +    return llvm::UndefValue::get(I32Ty); +  return llvm::ConstantInt::get(I32Ty, Off+MV); +} + +Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { +  bool Ignore = TestAndClearIgnoreResultAssign(); +  (void)Ignore; +  assert (Ignore == false && "init list ignored"); +  unsigned NumInitElements = E->getNumInits(); +   +  if (E->hadArrayRangeDesignator()) +    CGF.ErrorUnsupported(E, "GNU array range designator extension"); +   +  const llvm::VectorType *VType = +    dyn_cast<llvm::VectorType>(ConvertType(E->getType())); +   +  // We have a scalar in braces. Just use the first element. +  if (!VType) +    return Visit(E->getInit(0)); +   +  unsigned ResElts = VType->getNumElements(); +  const llvm::Type *I32Ty = llvm::Type::getInt32Ty(CGF.getLLVMContext()); +   +  // Loop over initializers collecting the Value for each, and remembering  +  // whether the source was swizzle (ExtVectorElementExpr).  This will allow +  // us to fold the shuffle for the swizzle into the shuffle for the vector +  // initializer, since LLVM optimizers generally do not want to touch +  // shuffles. +  unsigned CurIdx = 0; +  bool VIsUndefShuffle = false; +  llvm::Value *V = llvm::UndefValue::get(VType); +  for (unsigned i = 0; i != NumInitElements; ++i) { +    Expr *IE = E->getInit(i); +    Value *Init = Visit(IE); +    llvm::SmallVector<llvm::Constant*, 16> Args; +     +    const llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(Init->getType()); +     +    // Handle scalar elements.  If the scalar initializer is actually one +    // element of a different vector of the same width, use shuffle instead of  +    // extract+insert. +    if (!VVT) { +      if (isa<ExtVectorElementExpr>(IE)) { +        llvm::ExtractElementInst *EI = cast<llvm::ExtractElementInst>(Init); + +        if (EI->getVectorOperandType()->getNumElements() == ResElts) { +          llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand()); +          Value *LHS = 0, *RHS = 0; +          if (CurIdx == 0) { +            // insert into undef -> shuffle (src, undef) +            Args.push_back(C); +            for (unsigned j = 1; j != ResElts; ++j) +              Args.push_back(llvm::UndefValue::get(I32Ty)); + +            LHS = EI->getVectorOperand(); +            RHS = V; +            VIsUndefShuffle = true; +          } else if (VIsUndefShuffle) { +            // insert into undefshuffle && size match -> shuffle (v, src) +            llvm::ShuffleVectorInst *SVV = cast<llvm::ShuffleVectorInst>(V); +            for (unsigned j = 0; j != CurIdx; ++j) +              Args.push_back(getMaskElt(SVV, j, 0, I32Ty)); +            Args.push_back(llvm::ConstantInt::get(I32Ty,  +                                                  ResElts + C->getZExtValue())); +            for (unsigned j = CurIdx + 1; j != ResElts; ++j) +              Args.push_back(llvm::UndefValue::get(I32Ty)); +             +            LHS = cast<llvm::ShuffleVectorInst>(V)->getOperand(0); +            RHS = EI->getVectorOperand(); +            VIsUndefShuffle = false; +          } +          if (!Args.empty()) { +            llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], ResElts); +            V = Builder.CreateShuffleVector(LHS, RHS, Mask); +            ++CurIdx; +            continue; +          } +        } +      } +      Value *Idx = llvm::ConstantInt::get(I32Ty, CurIdx); +      V = Builder.CreateInsertElement(V, Init, Idx, "vecinit"); +      VIsUndefShuffle = false; +      ++CurIdx; +      continue; +    } +     +    unsigned InitElts = VVT->getNumElements(); + +    // If the initializer is an ExtVecEltExpr (a swizzle), and the swizzle's  +    // input is the same width as the vector being constructed, generate an +    // optimized shuffle of the swizzle input into the result. +    if (isa<ExtVectorElementExpr>(IE)) { +      llvm::ShuffleVectorInst *SVI = cast<llvm::ShuffleVectorInst>(Init); +      Value *SVOp = SVI->getOperand(0); +      const llvm::VectorType *OpTy = cast<llvm::VectorType>(SVOp->getType()); +       +      if (OpTy->getNumElements() == ResElts) { +        unsigned Offset = (CurIdx == 0) ? 0 : ResElts; +         +        for (unsigned j = 0; j != CurIdx; ++j) { +          // If the current vector initializer is a shuffle with undef, merge +          // this shuffle directly into it. +          if (VIsUndefShuffle) { +            Args.push_back(getMaskElt(cast<llvm::ShuffleVectorInst>(V), j, 0, +                                      I32Ty)); +          } else { +            Args.push_back(llvm::ConstantInt::get(I32Ty, j)); +          } +        } +        for (unsigned j = 0, je = InitElts; j != je; ++j) +          Args.push_back(getMaskElt(SVI, j, Offset, I32Ty)); +        for (unsigned j = CurIdx + InitElts; j != ResElts; ++j) +          Args.push_back(llvm::UndefValue::get(I32Ty)); + +        if (VIsUndefShuffle) +          V = cast<llvm::ShuffleVectorInst>(V)->getOperand(0); + +        Init = SVOp; +      } +    } + +    // Extend init to result vector length, and then shuffle its contribution +    // to the vector initializer into V. +    if (Args.empty()) { +      for (unsigned j = 0; j != InitElts; ++j) +        Args.push_back(llvm::ConstantInt::get(I32Ty, j)); +      for (unsigned j = InitElts; j != ResElts; ++j) +        Args.push_back(llvm::UndefValue::get(I32Ty)); +      llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], ResElts); +      Init = Builder.CreateShuffleVector(Init, llvm::UndefValue::get(VVT), +                                         Mask, "vecext"); + +      Args.clear(); +      for (unsigned j = 0; j != CurIdx; ++j) +        Args.push_back(llvm::ConstantInt::get(I32Ty, j)); +      for (unsigned j = 0; j != InitElts; ++j) +        Args.push_back(llvm::ConstantInt::get(I32Ty, j+ResElts)); +      for (unsigned j = CurIdx + InitElts; j != ResElts; ++j) +        Args.push_back(llvm::UndefValue::get(I32Ty)); +    } + +    // If V is undef, make sure it ends up on the RHS of the shuffle to aid +    // merging subsequent shuffles into this one. +    if (CurIdx == 0) +      std::swap(V, Init); +    llvm::Constant *Mask = llvm::ConstantVector::get(&Args[0], ResElts); +    V = Builder.CreateShuffleVector(V, Init, Mask, "vecinit"); +    VIsUndefShuffle = isa<llvm::UndefValue>(Init); +    CurIdx += InitElts; +  } +   +  // FIXME: evaluate codegen vs. shuffling against constant null vector. +  // Emit remaining default initializers. +  const llvm::Type *EltTy = VType->getElementType(); +   +  // Emit remaining default initializers +  for (/* Do not initialize i*/; CurIdx < ResElts; ++CurIdx) { +    Value *Idx = llvm::ConstantInt::get(I32Ty, CurIdx); +    llvm::Value *Init = llvm::Constant::getNullValue(EltTy); +    V = Builder.CreateInsertElement(V, Init, Idx, "vecinit"); +  } +  return V; +} +  // VisitCastExpr - Emit code for an explicit or implicit cast.  Implicit casts  // have to handle a more broad range of conversions than explicit casts, as they  // handle things like function to ptr-to-function decay etc. @@ -700,7 +835,16 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) {    case CastExpr::CK_IntegralToPointer: {      Value *Src = Visit(const_cast<Expr*>(E)); -    return Builder.CreateIntToPtr(Src, ConvertType(DestTy)); +     +    // First, convert to the correct width so that we control the kind of +    // extension. +    const llvm::Type *MiddleTy = +      llvm::IntegerType::get(VMContext, CGF.LLVMPointerWidth); +    bool InputSigned = E->getType()->isSignedIntegerType(); +    llvm::Value* IntResult = +      Builder.CreateIntCast(Src, MiddleTy, InputSigned, "conv"); +     +    return Builder.CreateIntToPtr(IntResult, ConvertType(DestTy));    }    case CastExpr::CK_PointerToIntegral: { @@ -1379,18 +1523,20 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {  }  Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { +  const llvm::Type *ResTy = ConvertType(E->getType()); +      // If we have 0 && RHS, see if we can elide RHS, if so, just return 0.    // If we have 1 && X, just emit X without inserting the control flow.    if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) {      if (Cond == 1) { // If we have 1 && X, just emit X.        Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); -      // ZExt result to int. -      return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "land.ext"); +      // ZExt result to int or bool. +      return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");      } -    // 0 && RHS: If it is safe, just elide the RHS, and return 0. +    // 0 && RHS: If it is safe, just elide the RHS, and return 0/false.      if (!CGF.ContainsLabel(E->getRHS())) -      return llvm::Constant::getNullValue(CGF.LLVMIntTy); +      return llvm::Constant::getNullValue(ResTy);    }    llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end"); @@ -1423,22 +1569,24 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {    PN->addIncoming(RHSCond, RHSBlock);    // ZExt result to int. -  return Builder.CreateZExt(PN, CGF.LLVMIntTy, "land.ext"); +  return Builder.CreateZExtOrBitCast(PN, ResTy, "land.ext");  }  Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { +  const llvm::Type *ResTy = ConvertType(E->getType()); +      // If we have 1 || RHS, see if we can elide RHS, if so, just return 1.    // If we have 0 || X, just emit X without inserting the control flow.    if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) {      if (Cond == -1) { // If we have 0 || X, just emit X.        Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); -      // ZExt result to int. -      return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "lor.ext"); +      // ZExt result to int or bool. +      return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");      } -    // 1 || RHS: If it is safe, just elide the RHS, and return 1. +    // 1 || RHS: If it is safe, just elide the RHS, and return 1/true.      if (!CGF.ContainsLabel(E->getRHS())) -      return llvm::ConstantInt::get(CGF.LLVMIntTy, 1); +      return llvm::ConstantInt::get(ResTy, 1);    }    llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end"); @@ -1474,7 +1622,7 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {    PN->addIncoming(RHSCond, RHSBlock);    // ZExt result to int. -  return Builder.CreateZExt(PN, CGF.LLVMIntTy, "lor.ext"); +  return Builder.CreateZExtOrBitCast(PN, ResTy, "lor.ext");  }  Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) { diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 4485ed5aee75..9b2f4a1faee7 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -850,7 +850,7 @@ protected:    /// \param[out] NameOut - The return value.    void GetNameForMethod(const ObjCMethodDecl *OMD,                          const ObjCContainerDecl *CD, -                        std::string &NameOut); +                        llvm::SmallVectorImpl<char> &NameOut);    /// GetMethodVarName - Return a unique constant for the given    /// selector's name. The return value has type char *. @@ -900,7 +900,7 @@ protected:    /// EmitPropertyList - Emit the given property list. The return    /// value has type PropertyListPtrTy. -  llvm::Constant *EmitPropertyList(const std::string &Name, +  llvm::Constant *EmitPropertyList(llvm::Twine Name,                                     const Decl *Container,                                     const ObjCContainerDecl *OCD,                                     const ObjCCommonTypesHelper &ObjCTypes); @@ -924,7 +924,7 @@ protected:    /// \param Align - The alignment for the variable, or 0.    /// \param AddToUsed - Whether the variable should be added to    /// "llvm.used". -  llvm::GlobalVariable *CreateMetadataVar(const std::string &Name, +  llvm::GlobalVariable *CreateMetadataVar(llvm::Twine Name,                                            llvm::Constant *Init,                                            const char *Section,                                            unsigned Align, @@ -1025,7 +1025,7 @@ private:    /// EmitMethodList - Emit the method list for the given    /// implementation. The return value has type MethodListPtrTy. -  llvm::Constant *EmitMethodList(const std::string &Name, +  llvm::Constant *EmitMethodList(llvm::Twine Name,                                   const char *Section,                                   const ConstantVector &Methods); @@ -1040,7 +1040,7 @@ private:    ///  - begin, end: The method list to output.    ///    /// The return value has type MethodDescriptionListPtrTy. -  llvm::Constant *EmitMethodDescList(const std::string &Name, +  llvm::Constant *EmitMethodDescList(llvm::Twine Name,                                       const char *Section,                                       const ConstantVector &Methods); @@ -1066,7 +1066,7 @@ private:    /// EmitProtocolList - Generate the list of referenced    /// protocols. The return value has type ProtocolListPtrTy. -  llvm::Constant *EmitProtocolList(const std::string &Name, +  llvm::Constant *EmitProtocolList(llvm::Twine Name,                                     ObjCProtocolDecl::protocol_iterator begin,                                     ObjCProtocolDecl::protocol_iterator end); @@ -1197,7 +1197,7 @@ private:    /// EmitMethodList - Emit the method list for the given    /// implementation. The return value has type MethodListnfABITy. -  llvm::Constant *EmitMethodList(const std::string &Name, +  llvm::Constant *EmitMethodList(llvm::Twine Name,                                   const char *Section,                                   const ConstantVector &Methods);    /// EmitIvarList - Emit the ivar list for the given @@ -1224,7 +1224,7 @@ private:    /// EmitProtocolList - Generate the list of referenced    /// protocols. The return value has type ProtocolListPtrTy. -  llvm::Constant *EmitProtocolList(const std::string &Name, +  llvm::Constant *EmitProtocolList(llvm::Twine Name,                                     ObjCProtocolDecl::protocol_iterator begin,                                     ObjCProtocolDecl::protocol_iterator end); @@ -1616,8 +1616,6 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {    // resolved. Investigate. Its also wasteful to look this up over and over.    LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); -  const char *ProtocolName = PD->getNameAsCString(); -    // Construct method lists.    std::vector<llvm::Constant*> InstanceMethods, ClassMethods;    std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; @@ -1647,17 +1645,15 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {    Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);    Values[1] = GetClassName(PD->getIdentifier());    Values[2] = -    EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getNameAsString(), +    EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),                       PD->protocol_begin(),                       PD->protocol_end());    Values[3] = -    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" -                       + PD->getNameAsString(), +    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),                         "__OBJC,__cat_inst_meth,regular,no_dead_strip",                         InstanceMethods);    Values[4] = -    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" -                       + PD->getNameAsString(), +    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),                         "__OBJC,__cat_cls_meth,regular,no_dead_strip",                         ClassMethods);    llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, @@ -1672,7 +1668,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,                                 llvm::GlobalValue::InternalLinkage,                                 Init, -                               std::string("\01L_OBJC_PROTOCOL_")+ProtocolName); +                               "\01L_OBJC_PROTOCOL_" + PD->getName());      Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");      Entry->setAlignment(4);      // FIXME: Is this necessary? Why only for protocol? @@ -1694,7 +1690,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,                                 llvm::GlobalValue::ExternalLinkage,                                 0, -                               "\01L_OBJC_PROTOCOL_" + PD->getNameAsString()); +                               "\01L_OBJC_PROTOCOL_" + PD->getName());      Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");      Entry->setAlignment(4);      // FIXME: Is this necessary? Why only for protocol? @@ -1722,16 +1718,14 @@ CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,    Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);    Values[1] =      EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" -                       + PD->getNameAsString(), +                       + PD->getName(),                         "__OBJC,__cat_inst_meth,regular,no_dead_strip",                         OptInstanceMethods);    Values[2] = -    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" -                       + PD->getNameAsString(), +    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),                         "__OBJC,__cat_cls_meth,regular,no_dead_strip",                         OptClassMethods); -  Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + -                               PD->getNameAsString(), +  Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(),                                 0, PD, ObjCTypes);    // Return null if no extension bits are used. @@ -1743,7 +1737,7 @@ CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,      llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);    // No special section, but goes in llvm.used -  return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getNameAsString(), +  return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),                             Init,                             0, 0, true);  } @@ -1756,7 +1750,7 @@ CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,    };  */  llvm::Constant * -CGObjCMac::EmitProtocolList(const std::string &Name, +CGObjCMac::EmitProtocolList(llvm::Twine Name,                              ObjCProtocolDecl::protocol_iterator begin,                              ObjCProtocolDecl::protocol_iterator end) {    std::vector<llvm::Constant*> ProtocolRefs; @@ -1800,7 +1794,7 @@ CGObjCMac::EmitProtocolList(const std::string &Name,    struct _objc_property[prop_count];    };  */ -llvm::Constant *CGObjCCommonMac::EmitPropertyList(const std::string &Name, +llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name,                                         const Decl *Container,                                         const ObjCContainerDecl *OCD,                                         const ObjCCommonTypesHelper &ObjCTypes) { @@ -1854,7 +1848,7 @@ CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {                                     Desc);  } -llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name, +llvm::Constant *CGObjCMac::EmitMethodDescList(llvm::Twine Name,                                                const char *Section,                                                const ConstantVector &Methods) {    // Return null for empty list. @@ -1894,8 +1888,10 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {    const ObjCInterfaceDecl *Interface = OCD->getClassInterface();    const ObjCCategoryDecl *Category =      Interface->FindCategoryDeclaration(OCD->getIdentifier()); -  std::string ExtName(Interface->getNameAsString() + "_" + -                      OCD->getNameAsString()); + +  llvm::SmallString<256> ExtName; +  llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_' +                                     << OCD->getName();    std::vector<llvm::Constant*> InstanceMethods, ClassMethods;    for (ObjCCategoryImplDecl::instmeth_iterator @@ -1914,17 +1910,16 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {    Values[1] = GetClassName(Interface->getIdentifier());    LazySymbols.insert(Interface->getIdentifier());    Values[2] = -    EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") + -                   ExtName, +    EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),                     "__OBJC,__cat_inst_meth,regular,no_dead_strip",                     InstanceMethods);    Values[3] = -    EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName, +    EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),                     "__OBJC,__cat_cls_meth,regular,no_dead_strip",                     ClassMethods);    if (Category) {      Values[4] = -      EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName, +      EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),                         Category->protocol_begin(),                         Category->protocol_end());    } else { @@ -1934,7 +1929,7 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {    // If there is no category @interface then there can be no properties.    if (Category) { -    Values[6] = EmitPropertyList(std::string("\01l_OBJC_$_PROP_LIST_")+ExtName, +    Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),                                   OCD, Category, ObjCTypes);    } else {      Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); @@ -1944,7 +1939,7 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {                                                     Values);    llvm::GlobalVariable *GV = -    CreateMetadataVar(std::string("\01L_OBJC_CATEGORY_")+ExtName, Init, +    CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,                        "__OBJC,__category,regular,no_dead_strip",                        4, true);    DefinedCategories.push_back(GV); @@ -1988,7 +1983,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {    ObjCInterfaceDecl *Interface =      const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());    llvm::Constant *Protocols = -    EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getNameAsString(), +    EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),                       Interface->protocol_begin(),                       Interface->protocol_end());    unsigned Flags = eClassFlags_Factory; @@ -2046,7 +2041,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {    Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);    Values[ 6] = EmitIvarList(ID, false);    Values[ 7] = -    EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getNameAsString(), +    EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),                     "__OBJC,__inst_meth,regular,no_dead_strip",                     InstanceMethods);    // cache is always NULL. @@ -2058,7 +2053,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {                                                     Values);    llvm::GlobalVariable *GV = -    CreateMetadataVar(std::string("\01L_OBJC_CLASS_")+ClassName, Init, +    CreateMetadataVar("\01L_OBJC_CLASS_" + ClassName, Init,                        "__OBJC,__class,regular,no_dead_strip",                        4, true);    DefinedClasses.push_back(GV); @@ -2174,7 +2169,7 @@ CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {    std::vector<llvm::Constant*> Values(3);    Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);    Values[1] = BuildIvarLayout(ID, false); -  Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getNameAsString(), +  Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),                                 ID, ID->getClassInterface(), ObjCTypes);    // Return null if no extension bits are used. @@ -2183,7 +2178,7 @@ CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {    llvm::Constant *Init =      llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); -  return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getNameAsString(), +  return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),                             Init, "__OBJC,__class_ext,regular,no_dead_strip",                             4, true);  } @@ -2243,12 +2238,11 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,    llvm::GlobalVariable *GV;    if (ForClass) -    GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getNameAsString(), +    GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),                             Init, "__OBJC,__class_vars,regular,no_dead_strip",                             4, true);    else -    GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" -                           + ID->getNameAsString(), +    GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),                             Init, "__OBJC,__instance_vars,regular,no_dead_strip",                             4, true);    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy); @@ -2286,7 +2280,7 @@ llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {    return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);  } -llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name, +llvm::Constant *CGObjCMac::EmitMethodList(llvm::Twine Name,                                            const char *Section,                                            const ConstantVector &Methods) {    // Return null for empty list. @@ -2308,7 +2302,7 @@ llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,  llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,                                                  const ObjCContainerDecl *CD) { -  std::string Name; +  llvm::SmallString<256> Name;    GetNameForMethod(OMD, CD, Name);    CodeGenTypes &Types = CGM.getTypes(); @@ -2317,7 +2311,7 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,    llvm::Function *Method =      llvm::Function::Create(MethodTy,                             llvm::GlobalValue::InternalLinkage, -                           Name, +                           Name.str(),                             &CGM.getModule());    MethodDefinitions.insert(std::make_pair(OMD, Method)); @@ -2325,7 +2319,7 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,  }  llvm::GlobalVariable * -CGObjCCommonMac::CreateMetadataVar(const std::string &Name, +CGObjCCommonMac::CreateMetadataVar(llvm::Twine Name,                                     llvm::Constant *Init,                                     const char *Section,                                     unsigned Align, @@ -2985,7 +2979,8 @@ llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {    if (!Entry)      Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", -                          llvm::ConstantArray::get(VMContext, Ident->getName()), +                          llvm::ConstantArray::get(VMContext, +                                                   Ident->getNameStart()),                                "__TEXT,__cstring,cstring_literals",                                1, true); @@ -3434,7 +3429,8 @@ llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {    if (!Entry)      Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_", -                          llvm::ConstantArray::get(VMContext, Ident->getName()), +                          llvm::ConstantArray::get(VMContext, +                                                   Ident->getNameStart()),                                "__TEXT,__cstring,cstring_literals",                                1, true); @@ -3453,21 +3449,15 @@ CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,  void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,                                         const ObjCContainerDecl *CD, -                                       std::string &NameOut) { -  NameOut = '\01'; -  NameOut += (D->isInstanceMethod() ? '-' : '+'); -  NameOut += '['; +                                       llvm::SmallVectorImpl<char> &Name) { +  llvm::raw_svector_ostream OS(Name);    assert (CD && "Missing container decl in GetNameForMethod"); -  NameOut += CD->getNameAsString(); +  OS << '\01' << (D->isInstanceMethod() ? '-' : '+') +     << '[' << CD->getName();    if (const ObjCCategoryImplDecl *CID = -      dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) { -    NameOut += '('; -    NameOut += CID->getNameAsString(); -    NameOut+= ')'; -  } -  NameOut += ' '; -  NameOut += D->getSelector().getAsString(); -  NameOut += ']'; +      dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) +    OS << '(' << CID->getNameAsString() << ')'; +  OS << ' ' << D->getSelector().getAsString() << ']';  }  void CGObjCMac::FinishModule() { @@ -4256,7 +4246,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    const ObjCInterfaceDecl *OID = ID->getClassInterface();    assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");    Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" -                                + OID->getNameAsString(), +                                + OID->getName(),                                  OID->protocol_begin(),                                  OID->protocol_end()); @@ -4269,9 +4259,8 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(    if (flags & CLS_META)      Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);    else -    Values[ 9] = -      EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getNameAsString(), -                       ID, ID->getClassInterface(), ObjCTypes); +    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), +                                  ID, ID->getClassInterface(), ObjCTypes);    llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,                                                     Values);    llvm::GlobalVariable *CLASS_RO_GV = @@ -4532,16 +4521,16 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {    const ObjCCategoryDecl *Category =      Interface->FindCategoryDeclaration(OCD->getIdentifier());    if (Category) { -    std::string ExtName(Interface->getNameAsString() + "_$_" + -                        OCD->getNameAsString()); +    llvm::SmallString<256> ExtName; +    llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_" +                                       << OCD->getName();      Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" -                                 + Interface->getNameAsString() + "_$_" -                                 + Category->getNameAsString(), +                                 + Interface->getName() + "_$_" +                                 + Category->getName(),                                   Category->protocol_begin(),                                   Category->protocol_end()); -    Values[5] = -      EmitPropertyList(std::string("\01l_OBJC_$_PROP_LIST_") + ExtName, -                       OCD, Category, ObjCTypes); +    Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), +                                 OCD, Category, ObjCTypes);    } else {      Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);      Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); @@ -4593,10 +4582,9 @@ llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(  ///   struct _objc_method method_list[method_count];  /// }  /// -llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( -  const std::string &Name, -  const char *Section, -  const ConstantVector &Methods) { +llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(llvm::Twine Name, +                                                       const char *Section, +                                                const ConstantVector &Methods) {    // Return null for empty list.    if (Methods.empty())      return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); @@ -4742,7 +4730,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(      new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,                               llvm::GlobalValue::InternalLinkage,                               Init, -                             Prefix + OID->getNameAsString()); +                             Prefix + OID->getName());    GV->setAlignment(      CGM.getTargetData().getPrefTypeAlignment(Init->getType()));    GV->setSection("__DATA, __objc_const"); @@ -4763,7 +4751,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,                                 llvm::GlobalValue::ExternalLinkage,                                 0, -                               "\01l_OBJC_PROTOCOL_$_" + PD->getNameAsString()); +                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());      Entry->setSection("__DATA,__datacoal_nt,coalesced");    } @@ -4795,8 +4783,6 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(    if (Entry && Entry->hasInitializer())      return Entry; -  const char *ProtocolName = PD->getNameAsCString(); -    // Construct method lists.    std::vector<llvm::Constant*> InstanceMethods, ClassMethods;    std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; @@ -4826,28 +4812,27 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(    // isa is NULL    Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);    Values[1] = GetClassName(PD->getIdentifier()); -  Values[2] = EmitProtocolList( -    "\01l_OBJC_$_PROTOCOL_REFS_" + PD->getNameAsString(), -    PD->protocol_begin(), -    PD->protocol_end()); +  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(), +                               PD->protocol_begin(), +                               PD->protocol_end());    Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_" -                             + PD->getNameAsString(), +                             + PD->getName(),                               "__DATA, __objc_const",                               InstanceMethods);    Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" -                             + PD->getNameAsString(), +                             + PD->getName(),                               "__DATA, __objc_const",                               ClassMethods);    Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_" -                             + PD->getNameAsString(), +                             + PD->getName(),                               "__DATA, __objc_const",                               OptInstanceMethods);    Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" -                             + PD->getNameAsString(), +                             + PD->getName(),                               "__DATA, __objc_const",                               OptClassMethods); -  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getNameAsString(), +  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),                                 0, PD, ObjCTypes);    uint32_t Size =      CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); @@ -4862,10 +4847,9 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(      Entry->setInitializer(Init);    } else {      Entry = -      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false, -                               llvm::GlobalValue::WeakAnyLinkage, -                               Init, -                               std::string("\01l_OBJC_PROTOCOL_$_")+ProtocolName); +      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, +                               false, llvm::GlobalValue::WeakAnyLinkage, Init, +                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());      Entry->setAlignment(        CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABITy));      Entry->setSection("__DATA,__datacoal_nt,coalesced"); @@ -4875,13 +4859,10 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(    // Use this protocol meta-data to build protocol list table in section    // __DATA, __objc_protolist -  llvm::GlobalVariable *PTGV = new llvm::GlobalVariable( -    CGM.getModule(), -    ObjCTypes.ProtocolnfABIPtrTy, false, -    llvm::GlobalValue::WeakAnyLinkage, -    Entry, -    std::string("\01l_OBJC_LABEL_PROTOCOL_$_") -    +ProtocolName); +  llvm::GlobalVariable *PTGV = +    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, +                             false, llvm::GlobalValue::WeakAnyLinkage, Entry, +                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());    PTGV->setAlignment(      CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));    PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); @@ -4899,9 +4880,9 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(  /// @endcode  ///  llvm::Constant * -CGObjCNonFragileABIMac::EmitProtocolList(const std::string &Name, -                                         ObjCProtocolDecl::protocol_iterator begin, -                                         ObjCProtocolDecl::protocol_iterator end) { +CGObjCNonFragileABIMac::EmitProtocolList(llvm::Twine Name, +                                      ObjCProtocolDecl::protocol_iterator begin, +                                      ObjCProtocolDecl::protocol_iterator end) {    std::vector<llvm::Constant*> ProtocolRefs;    // Just return null for empty protocol lists @@ -4909,10 +4890,12 @@ CGObjCNonFragileABIMac::EmitProtocolList(const std::string &Name,      return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);    // FIXME: We shouldn't need to do this lookup here, should we? -  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true); +  llvm::SmallString<256> TmpName; +  Name.toVector(TmpName); +  llvm::GlobalVariable *GV = +    CGM.getModule().getGlobalVariable(TmpName.str(), true);    if (GV) -    return llvm::ConstantExpr::getBitCast(GV, -                                          ObjCTypes.ProtocolListnfABIPtrTy); +    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);    for (; begin != end; ++begin)      ProtocolRefs.push_back(GetProtocolRef(*begin));  // Implemented??? @@ -5683,7 +5666,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,          new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,                                   llvm::GlobalValue::ExternalLinkage,                                   0, -                                 (std::string("OBJC_EHTYPE_$_") + +                                 ("OBJC_EHTYPE_$_" +                                    ID->getIdentifier()->getName()));    } @@ -5715,7 +5698,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,      Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,                                       llvm::GlobalValue::WeakAnyLinkage,                                       Init, -                                     (std::string("OBJC_EHTYPE_$_") + +                                     ("OBJC_EHTYPE_$_" +                                        ID->getIdentifier()->getName()));    } diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 6e73db359af1..9df0e1abd547 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -119,6 +119,43 @@ public:    Index_t VBlookup(CXXRecordDecl *D, CXXRecordDecl *B); +  Index_t getNVOffset_1(const CXXRecordDecl *D, const CXXRecordDecl *B, +    Index_t Offset = 0) { + +    if (B == D) +      return Offset; + +    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(D); +    for (CXXRecordDecl::base_class_const_iterator i = D->bases_begin(), +           e = D->bases_end(); i != e; ++i) { +      const CXXRecordDecl *Base = +        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); +      int64_t BaseOffset = 0; +      if (!i->isVirtual()) +        BaseOffset = Offset + Layout.getBaseClassOffset(Base); +      int64_t o = getNVOffset_1(Base, B, BaseOffset); +      if (o >= 0) +        return o; +    } + +    return -1; +  } + +  /// getNVOffset - Returns the non-virtual offset for the given (B) base of the +  /// derived class D. +  Index_t getNVOffset(QualType qB, QualType qD) { +    qD = qD->getAs<PointerType>()->getPointeeType(); +    qB = qB->getAs<PointerType>()->getPointeeType(); +    CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl()); +    CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl()); +    int64_t o = getNVOffset_1(D, B); +    if (o >= 0) +      return o; + +    assert(false && "FIXME: non-virtual base not found"); +    return 0; +  } +    /// getVbaseOffset - Returns the index into the vtable for the virtual base    /// offset for the given (B) virtual base of the derived class D.    Index_t getVbaseOffset(QualType qB, QualType qD) { @@ -138,8 +175,10 @@ public:    }    bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m, -                      bool MorallyVirtual, Index_t Offset) { +                      bool MorallyVirtual, Index_t OverrideOffset, +                      Index_t Offset) {      typedef CXXMethodDecl::method_iterator meth_iter; +    // FIXME: Should OverrideOffset's be Offset?      // FIXME: Don't like the nested loops.  For very large inheritance      // heirarchies we could have a table on the side with the final overridder @@ -166,11 +205,12 @@ public:          CallOffset ReturnOffset = std::make_pair(0, 0);          if (oret != ret) {            // FIXME: calculate offsets for covariance -          Index_t nv = 0;            if (CovariantThunks.count(OMD)) {              oret = CovariantThunks[OMD].second;              CovariantThunks.erase(OMD);            } +          // FIXME: Double check oret +          Index_t nv = getNVOffset(oret, ret)/8;            ReturnOffset = std::make_pair(nv, getVbaseOffset(oret, ret));          }          Index[MD] = i; @@ -180,17 +220,16 @@ public:          if (MorallyVirtual) {            Index_t &idx = VCall[OMD];            if (idx == 0) { -            VCallOffset[MD] = Offset/8; +            VCallOffset[MD] = OverrideOffset/8;              idx = VCalls.size()+1;              VCalls.push_back(0);            } else {              VCallOffset[MD] = VCallOffset[OMD]; -            VCalls[idx-1] = -VCallOffset[OMD] + Offset/8; +            VCalls[idx-1] = -VCallOffset[OMD] + OverrideOffset/8;            }            VCall[MD] = idx;            CallOffset ThisOffset; -          // FIXME: calculate non-virtual offset -          ThisOffset = std::make_pair(0 /* -CurrentVBaseOffset/8 + Offset/8 */, +          ThisOffset = std::make_pair(CurrentVBaseOffset/8 - Offset/8,                                        -((idx+extra+2)*LLVMPointerWidth/8));            // FIXME: Do we always have to build a covariant thunk to save oret,            // which is the containing virtual base class? @@ -204,8 +243,8 @@ public:          }          // FIXME: finish off -        int64_t O = VCallOffset[OMD] - Offset/8; -        // int64_t O = CurrentVBaseOffset/8 - Offset/8; +        int64_t O = VCallOffset[OMD] - OverrideOffset/8; +        // int64_t O = CurrentVBaseOffset/8 - OverrideOffset/8;          if (O || ReturnOffset.first || ReturnOffset.second) {            CallOffset ThisOffset = std::make_pair(O, 0); @@ -248,11 +287,11 @@ public:      CovariantThunks.clear();    } -  void OverrideMethods(Path_t *Path, bool MorallyVirtual) { +  void OverrideMethods(Path_t *Path, bool MorallyVirtual, int64_t Offset) {      for (Path_t::reverse_iterator i = Path->rbegin(),             e = Path->rend(); i != e; ++i) {        const CXXRecordDecl *RD = i->first; -      int64_t Offset = i->second; +      int64_t OverrideOffset = i->second;        for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;             ++mi) {          if (!mi->isVirtual()) @@ -272,7 +311,7 @@ public:            m = wrap(CGM.GetAddrOfFunction(MD, Ty));          } -        OverrideMethod(MD, m, MorallyVirtual, Offset); +        OverrideMethod(MD, m, MorallyVirtual, OverrideOffset, Offset);        }      }    } @@ -291,7 +330,7 @@ public:      }      // If we can find a previously allocated slot for this, reuse it. -    if (OverrideMethod(MD, m, MorallyVirtual, Offset)) +    if (OverrideMethod(MD, m, MorallyVirtual, Offset, Offset))        return;      // else allocate a new slot. @@ -344,7 +383,7 @@ public:      llvm::Constant *e = 0;      D(VCalls.insert(VCalls.begin(), 673));      D(VCalls.push_back(672)); -    methods.insert(methods.begin() + InsertionPoint, VCalls.size()/*+2*/, e); +    methods.insert(methods.begin() + InsertionPoint, VCalls.size(), e);      // The vcalls come first...      for (std::vector<Index_t>::reverse_iterator i = VCalls.rbegin(),             e = VCalls.rend(); @@ -380,7 +419,9 @@ public:      int VCallInsertionPoint = methods.size();      if (!DeferVCalls) {        insertVCalls(VCallInsertionPoint); -    } +    } else +      // FIXME: just for extra, or for all uses of VCalls.size post this? +      extra = -VCalls.size();      if (ForVirtualBase) {        D(methods.push_back(wrap(668))); @@ -463,7 +504,7 @@ public:      AddMethods(RD, MorallyVirtual, Offset);      if (Path) -      OverrideMethods(Path, MorallyVirtual); +      OverrideMethods(Path, MorallyVirtual, Offset);      return end(RD, offsets, Layout, PrimaryBase, PrimaryBaseWasVirtual,                 MorallyVirtual, Offset, ForVirtualBase, Path); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 5206f447f8d0..ba93e5d0ebc8 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -167,18 +167,20 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,    Builder.SetInsertPoint(EntryBB); +  QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0); +    // Emit subprogram debug descriptor.    // FIXME: The cast here is a huge hack.    if (CGDebugInfo *DI = getDebugInfo()) {      DI->setLocation(StartLoc);      if (isa<FunctionDecl>(D)) { -      DI->EmitFunctionStart(CGM.getMangledName(GD), RetTy, CurFn, Builder); +      DI->EmitFunctionStart(CGM.getMangledName(GD), FnType, CurFn, Builder);      } else {        // Just use LLVM function name.        // FIXME: Remove unnecessary conversion to std::string when API settles.        DI->EmitFunctionStart(std::string(Fn->getName()).c_str(), -                            RetTy, CurFn, Builder); +                            FnType, CurFn, Builder);      }    } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 722d002c19f5..639e683f0369 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -34,6 +34,7 @@ namespace llvm {    class LLVMContext;    class Module;    class SwitchInst; +  class Twine;    class Value;  } @@ -355,6 +356,7 @@ public:    void BlockForwardSelf();    llvm::Value *LoadBlockStruct(); +  uint64_t AllocateBlockDecl(const BlockDeclRefExpr *E);    llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);    const llvm::Type *BuildByRefType(const ValueDecl *D); @@ -508,7 +510,7 @@ public:    /// CreateTempAlloca - This creates a alloca and inserts it into the entry    /// block.    llvm::AllocaInst *CreateTempAlloca(const llvm::Type *Ty, -                                     const char *Name = "tmp"); +                                     const llvm::Twine &Name = "tmp");    /// EvaluateExprAsBool - Perform the usual unary conversions on the specified    /// expression and compare the result against zero, returning an Int1Ty value. @@ -816,7 +818,9 @@ public:    LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);    LValue EmitConditionalOperatorLValue(const ConditionalOperator *E);    LValue EmitCastLValue(const CastExpr *E); - +  LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E); +  LValue EmitPointerToDataMemberLValue(const QualifiedDeclRefExpr *E); +      llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,                                const ObjCIvarDecl *Ivar);    LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field, @@ -841,7 +845,8 @@ public:    LValue EmitObjCKVCRefLValue(const ObjCImplicitSetterGetterRefExpr *E);    LValue EmitObjCSuperExprLValue(const ObjCSuperExpr *E);    LValue EmitStmtExprLValue(const StmtExpr *E); - +  LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E); +      //===--------------------------------------------------------------------===//    //                         Scalar Expression Emission    //===--------------------------------------------------------------------===// diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 4763b7fc1ee2..ea84829b78a5 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -825,7 +825,7 @@ llvm::Constant *  CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy,                                       const char *Name) {    // Convert Name to be a uniqued string from the IdentifierInfo table. -  Name = getContext().Idents.get(Name).getName(); +  Name = getContext().Idents.get(Name).getNameStart();    return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl());  } @@ -911,7 +911,7 @@ llvm::Constant *  CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,                                       const char *Name) {    // Convert Name to be a uniqued string from the IdentifierInfo table. -  Name = getContext().Idents.get(Name).getName(); +  Name = getContext().Idents.get(Name).getNameStart();    return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0);  } @@ -1254,7 +1254,7 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {    // Unique the name through the identifier table.    const char *AliaseeName = AA->getAliasee().c_str(); -  AliaseeName = getContext().Idents.get(AliaseeName).getName(); +  AliaseeName = getContext().Idents.get(AliaseeName).getNameStart();    // Create a reference to the named value.  This ensures that it is emitted    // if a deferred decl. @@ -1341,7 +1341,7 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,      cast<llvm::FunctionType>(getTypes().ConvertType(Type));    // Unique the name through the identifier table. -  Name = getContext().Idents.get(Name).getName(); +  Name = getContext().Idents.get(Name).getNameStart();    return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD));  } diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index fd772748dbda..2e6034bbcd97 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -248,7 +248,12 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {      FD = PrimaryTemplate->getTemplatedDecl();    } -  mangleBareFunctionType(FD->getType()->getAs<FunctionType>(), MangleReturnType); +  // Do the canonicalization out here because parameter types can +  // undergo additional canonicalization (e.g. array decay). +  FunctionType *FT = cast<FunctionType>(Context.getASTContext() +                                          .getCanonicalType(FD->getType())); + +  mangleBareFunctionType(FT, MangleReturnType);  }  static bool isStdNamespace(const DeclContext *DC) { @@ -705,7 +710,7 @@ void CXXNameMangler::mangleType(QualType T) {    // Only operate on the canonical type!    T = Context.getASTContext().getCanonicalType(T); -  bool IsSubstitutable = !isa<BuiltinType>(T); +  bool IsSubstitutable = T.hasQualifiers() || !isa<BuiltinType>(T);    if (IsSubstitutable && mangleSubstitution(T))      return; @@ -1236,10 +1241,7 @@ static bool isCharSpecialization(QualType T, const char *Name) {    if (!isCharType(TemplateArgs[0].getAsType()))      return false; -  if (strcmp(SD->getIdentifier()->getName(), Name) != 0) -    return false; - -  return true; +  return SD->getIdentifier()->getName() == Name;  }  bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) { diff --git a/lib/CodeGen/TargetABIInfo.cpp b/lib/CodeGen/TargetABIInfo.cpp index 59f579f7b17e..852bba4ef033 100644 --- a/lib/CodeGen/TargetABIInfo.cpp +++ b/lib/CodeGen/TargetABIInfo.cpp @@ -353,11 +353,17 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,      return ABIArgInfo::getDirect();    } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { -    // Structures with flexible arrays are always indirect. -    if (const RecordType *RT = RetTy->getAsStructureType()) +    if (const RecordType *RT = RetTy->getAsStructureType()) { +      // Structures with either a non-trivial destructor or a non-trivial +      // copy constructor are always indirect. +      if (hasNonTrivialDestructorOrCopyConstructor(RT)) +        return ABIArgInfo::getIndirect(0, /*ByVal=*/false); +       +      // Structures with flexible arrays are always indirect.        if (RT->getDecl()->hasFlexibleArrayMember())          return ABIArgInfo::getIndirect(0); - +    } +          // If specified, structs and unions are always indirect.      if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType())        return ABIArgInfo::getIndirect(0); @@ -1744,14 +1750,14 @@ const ABIInfo &CodeGenTypes::getABIInfo() const {      return *(TheABIInfo = new SystemZABIInfo());    case llvm::Triple::x86: -    if (Triple.getOS() == llvm::Triple::Darwin) -      return *(TheABIInfo = new X86_32ABIInfo(Context, true, true)); -      switch (Triple.getOS()) { +    case llvm::Triple::Darwin: +      return *(TheABIInfo = new X86_32ABIInfo(Context, true, true));      case llvm::Triple::Cygwin: -    case llvm::Triple::DragonFly:      case llvm::Triple::MinGW32:      case llvm::Triple::MinGW64: +    case llvm::Triple::AuroraUX: +    case llvm::Triple::DragonFly:      case llvm::Triple::FreeBSD:      case llvm::Triple::OpenBSD:        return *(TheABIInfo = new X86_32ABIInfo(Context, false, true)); | 
