Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -238,6 +238,13 @@ llvm::DIScope *scope, const RecordDecl *RD = nullptr); + llvm::DIType *createFieldType(StringRef Name, QualType Type, + SourceLocation Loc, uint64_t AlignInBits, + uint64_t OffsetInBits, + llvm::DINode::DIFlags Flags, + llvm::DIFile *TUnit, llvm::DIScope *Scope, + const RecordDecl *RD = nullptr); + /// Create new bit field member. llvm::DIType *createBitFieldType(const FieldDecl *BitFieldDecl, llvm::DIScope *RecordTy, Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -999,6 +999,28 @@ AlignInBits, offsetInBits, flags, debugType); } +llvm::DIType * +CGDebugInfo::createFieldType(StringRef Name, QualType Type, SourceLocation Loc, + uint64_t AlignInBits, uint64_t OffsetInBits, + llvm::DINode::DIFlags Flags, + llvm::DIFile *TUnit, llvm::DIScope *Scope, + const RecordDecl *RD) { + llvm::DIType *DebugType = getOrCreateType(Type, TUnit); + + // Get the location for the field. + llvm::DIFile *File = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); + + uint64_t SizeInBits = 0; + if (!Type->isIncompleteArrayType()) { + TypeInfo TI = CGM.getContext().getTypeInfo(Type); + SizeInBits = TI.Width; + } + + return DBuilder.createMemberType(Scope, Name, File, Line, SizeInBits, + AlignInBits, OffsetInBits, Flags, DebugType); +} + void CGDebugInfo::CollectRecordLambdaFields( const CXXRecordDecl *CXXDecl, SmallVectorImpl &elements, llvm::DIType *RecordTy) { @@ -1012,15 +1034,21 @@ E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) { const LambdaCapture &C = *I; + uint64_t AlignInBits = 0; + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; if (C.capturesVariable()) { SourceLocation Loc = C.getLocation(); assert(!Field->isBitField() && "lambdas don't have bitfield members!"); VarDecl *V = C.getCapturedVar(); StringRef VName = V->getName(); + AlignInBits = V->getMaxAlignment(); + Flags |= getAccessFlag(Field->getAccess(), CXXDecl); + if (V->hasAttr()) + Flags |= llvm::DINode::FlagAlignment; llvm::DIFile *VUnit = getOrCreateFile(Loc); llvm::DIType *FieldType = createFieldType( - VName, Field->getType(), Loc, Field->getAccess(), - layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl); + VName, Field->getType(), Loc, AlignInBits, + layout.getFieldOffset(fieldno), Flags, VUnit, RecordTy, CXXDecl); elements.push_back(FieldType); } else if (C.capturesThis()) { // TODO: Need to handle 'this' in some way by probably renaming the @@ -1061,9 +1089,14 @@ } } + uint64_t AlignInBits = 0; llvm::DINode::DIFlags Flags = getAccessFlag(Var->getAccess(), RD); + if (Var->hasAttr()) { + Flags |= llvm::DINode::FlagAlignment; + AlignInBits = Var->getMaxAlignment(); + } llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( - RecordTy, VName, VUnit, LineNumber, VTy, Flags, C); + RecordTy, VName, VUnit, LineNumber, VTy, AlignInBits, Flags, C); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); return GV; } @@ -1074,6 +1107,14 @@ const RecordDecl *RD) { StringRef name = field->getName(); QualType type = field->getType(); + uint64_t AlignInBits = 0; + llvm::DINode::DIFlags Flags = getAccessFlag(field->getAccess(), RD); + if (field->hasAttr()) { + Flags |= llvm::DINode::FlagAlignment; + AlignInBits = field->getMaxAlignment(); + } else if (!type->isIncompleteArrayType()) { + AlignInBits = CGM.getContext().getTypeInfo(type).Align; + } // Ignore unnamed fields unless they're anonymous structs/unions. if (name.empty() && !type->isRecordType()) @@ -1084,8 +1125,8 @@ FieldType = createBitFieldType(field, RecordTy, RD); } else { FieldType = - createFieldType(name, type, field->getLocation(), field->getAccess(), - OffsetInBits, tunit, RecordTy, RD); + createFieldType(name, type, field->getLocation(), AlignInBits, + OffsetInBits, Flags, tunit, RecordTy, RD); } elements.push_back(FieldType); @@ -1972,6 +2013,8 @@ llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; if (ID->getImplementation()) Flags |= llvm::DINode::FlagObjcClassComplete; + if (ID->hasAttr()) + Flags |= llvm::DINode::FlagAlignment; llvm::DIScope *Mod = getParentModuleOrNull(ID); llvm::DICompositeType *RealDecl = DBuilder.createStructType( @@ -2086,6 +2129,9 @@ else if (Field->getAccessControl() == ObjCIvarDecl::Public) Flags = llvm::DINode::FlagPublic; + if (Field->hasAttr()) + Flags |= llvm::DINode::FlagAlignment; + llvm::MDNode *PropertyNode = nullptr; if (ObjCImplementationDecl *ImpD = ID->getImplementation()) { if (ObjCPropertyImplDecl *PImpD = @@ -2287,12 +2333,15 @@ llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); + llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl; + if (ED->hasAttr()) + Flags |= llvm::DINode::FlagAlignment; unsigned Line = getLineNumber(ED->getLocation()); StringRef EDName = ED->getName(); llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line, - 0, Size, Align, llvm::DINode::FlagFwdDecl, FullName); + 0, Size, Align, Flags, FullName); ReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(Ty), @@ -2307,10 +2356,13 @@ const EnumDecl *ED = Ty->getDecl(); uint64_t Size = 0; uint64_t Align = 0; + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; if (!ED->getTypeForDecl()->isIncompleteType()) { Size = CGM.getContext().getTypeSize(ED->getTypeForDecl()); Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl()); } + if (Align && ED->hasAttr()) + Flags |= llvm::DINode::FlagAlignment; SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU); @@ -2331,8 +2383,8 @@ llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, - Line, Size, Align, EltArray, ClassTy, - FullName); + Line, Size, Align, Flags, EltArray, + ClassTy, FullName); } static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) { @@ -2605,12 +2657,15 @@ uint64_t Size = CGM.getContext().getTypeSize(Ty); uint64_t Align = CGM.getContext().getTypeAlign(Ty); + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + if (RD->hasAttr()) + Flags |= llvm::DINode::FlagAlignment; SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU); llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType( getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align, - llvm::DINode::FlagZero, FullName); + Flags, FullName); // Elements of composite types usually have back to the type, creating // uniquing cycles. Distinct nodes are more efficient. @@ -2805,11 +2860,18 @@ llvm::DIFile *Unit = getOrCreateFile(Loc); llvm::DIScope *DContext = Unit; unsigned Line = getLineNumber(Loc); + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + uint64_t AlignInBits = 0; + + if (VD->hasAttr()) { + Flags |= llvm::DINode::FlagAlignment; + AlignInBits = VD->getMaxAlignment(); + } collectVarDeclProps(VD, Unit, Line, T, Name, LinkageName, DContext); auto *GV = DBuilder.createTempGlobalVariableFwdDecl( DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit), - !VD->isExternallyVisible(), nullptr, nullptr); + !VD->isExternallyVisible(), AlignInBits, Flags, nullptr, nullptr); FwdDeclReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(cast(VD->getCanonicalDecl())), @@ -3185,11 +3247,14 @@ llvm::DIType *FieldTy = getOrCreateType(FType, Unit); FieldSize = CGM.getContext().getTypeSize(FType); FieldAlign = CGM.getContext().toBits(Align); + llvm::DINode::DIFlags FieldFlags = llvm::DINode::FlagZero; + if (VD->hasAttr()) + FieldFlags |= llvm::DINode::FlagAlignment; *XOffset = FieldOffset; FieldTy = DBuilder.createMemberType(Unit, VD->getName(), Unit, 0, FieldSize, - FieldAlign, FieldOffset, - llvm::DINode::FlagZero, FieldTy); + FieldAlign, FieldOffset, FieldFlags, + FieldTy); EltTys.push_back(FieldTy); FieldOffset += FieldSize; @@ -3235,9 +3300,14 @@ Column = getColumnNumber(VD->getLocation()); } SmallVector Expr; + uint64_t AlignInBits = 0; llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; if (VD->isImplicit()) Flags |= llvm::DINode::FlagArtificial; + if (VD->hasAttr()) { + Flags |= llvm::DINode::FlagAlignment; + AlignInBits = VD->getMaxAlignment(); + } // If this is the first argument and it is implicit then // give it an object pointer flag. // FIXME: There has to be a better way to do this, but for static @@ -3272,7 +3342,9 @@ ? DBuilder.createParameterVariable(Scope, VD->getName(), *ArgNo, Unit, Line, Ty) : DBuilder.createAutoVariable(Scope, VD->getName(), Unit, - Line, Ty); + Line, Ty, + /* AlwaysPreserve */ false, + AlignInBits, Flags); // Insert an llvm.dbg.declare into the current block. DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr), @@ -3304,7 +3376,7 @@ // Use VarDecl's Tag, Scope and Line number. auto *D = DBuilder.createAutoVariable( Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize, - Flags | llvm::DINode::FlagArtificial); + AlignInBits, Flags | llvm::DINode::FlagArtificial); // Insert an llvm.dbg.declare into the current block. DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr), @@ -3321,7 +3393,8 @@ Ty, CGM.getLangOpts().Optimize, Flags) : DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty, - CGM.getLangOpts().Optimize, Flags); + CGM.getLangOpts().Optimize, + AlignInBits, Flags); // Insert an llvm.dbg.declare into the current block. DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr), @@ -3374,6 +3447,14 @@ unsigned Line = getLineNumber(VD->getLocation()); unsigned Column = getColumnNumber(VD->getLocation()); + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + uint64_t Align = 0; + + if (VD->hasAttr()) { + Flags |= llvm::DINode::FlagAlignment; + Align = VD->getMaxAlignment(); + } + const llvm::DataLayout &target = CGM.getDataLayout(); CharUnits offset = CharUnits::fromQuantity( @@ -3402,7 +3483,7 @@ // Create the descriptor for the variable. auto *D = DBuilder.createAutoVariable( cast(LexicalBlockStack.back()), VD->getName(), Unit, - Line, Ty); + Line, Ty, /* AlwaysPreserve */ false, Align, Flags); // Insert an llvm.dbg.declare into the current block. auto DL = llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back()); @@ -3615,10 +3696,19 @@ Var, DContext); continue; } + + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + uint64_t AlignInBits = 0; + auto Q = Var->getAlignment(); + if (Q) { + AlignInBits = RD->getASTContext().toBits(CharUnits::fromQuantity(Q)); + Flags |= llvm::DINode::FlagAlignment; + } + // Use VarDecl's Tag, Scope and Line number. GV = DBuilder.createGlobalVariable(DContext, FieldName, LinkageName, Unit, - LineNo, FieldTy, - Var->hasLocalLinkage(), Var, nullptr); + LineNo, FieldTy, Var->hasLocalLinkage(), + AlignInBits, Flags, Var, nullptr); } return GV; } @@ -3632,6 +3722,12 @@ llvm::DIFile *Unit = nullptr; llvm::DIScope *DContext = nullptr; unsigned LineNo; + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + uint64_t AlignInBits = 0; + if (D->hasAttr()) { + Flags |= llvm::DINode::FlagAlignment; + AlignInBits = D->getMaxAlignment(); + } StringRef DeclName, LinkageName; QualType T; collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName, DContext); @@ -3651,7 +3747,7 @@ } else { GV = DBuilder.createGlobalVariable( DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit), - Var->hasLocalLinkage(), Var, + Var->hasLocalLinkage(), AlignInBits, Flags, Var, getOrCreateStaticDataMemberDeclarationOrNull(D)); } DeclCache[D->getCanonicalDecl()].reset(GV); @@ -3698,9 +3794,17 @@ auto &GV = DeclCache[VD]; if (GV) return; + + uint64_t AlignInBits = 0; + llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + if (VD->hasAttr()) { + Flags |= llvm::DINode::FlagAlignment; + AlignInBits = VD->getMaxAlignment(); + } GV.reset(DBuilder.createGlobalVariable( DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty, - true, Init, getOrCreateStaticDataMemberDeclarationOrNull(VarD))); + true, AlignInBits, Flags, Init, + getOrCreateStaticDataMemberDeclarationOrNull(VarD))); } llvm::DIScope *CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {