Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -232,10 +232,17 @@ CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS, llvm::DIFile *F); - llvm::DIType *createFieldType(StringRef name, QualType type, - SourceLocation loc, AccessSpecifier AS, - uint64_t offsetInBits, llvm::DIFile *tunit, - llvm::DIScope *scope, + llvm::DIType *createFieldType(StringRef Name, QualType Type, + SourceLocation Loc, AccessSpecifier AS, + uint64_t OffsetInBits, + llvm::DIFile *TUnit, 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. Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -976,27 +976,49 @@ } llvm::DIType * -CGDebugInfo::createFieldType(StringRef name, QualType type, SourceLocation loc, - AccessSpecifier AS, uint64_t offsetInBits, - llvm::DIFile *tunit, llvm::DIScope *scope, +CGDebugInfo::createFieldType(StringRef Name, QualType Type, SourceLocation Loc, + AccessSpecifier AS, uint64_t OffsetInBits, + llvm::DIFile *TUnit, llvm::DIScope *Scope, const RecordDecl *RD) { - llvm::DIType *debugType = getOrCreateType(type, tunit); + llvm::DIType *DebugType = getOrCreateType(Type, TUnit); // Get the location for the field. - llvm::DIFile *file = getOrCreateFile(loc); - unsigned line = getLineNumber(loc); + llvm::DIFile *File = getOrCreateFile(Loc); + unsigned Line = getLineNumber(Loc); uint64_t SizeInBits = 0; - unsigned AlignInBits = 0; - if (!type->isIncompleteArrayType()) { - TypeInfo TI = CGM.getContext().getTypeInfo(type); + uint64_t AlignInBits = 0; + if (!Type->isIncompleteArrayType()) { + TypeInfo TI = CGM.getContext().getTypeInfo(Type); SizeInBits = TI.Width; AlignInBits = TI.Align; } + llvm::DINode::DIFlags Flags = getAccessFlag(AS, RD); - llvm::DINode::DIFlags flags = getAccessFlag(AS, RD); - return DBuilder.createMemberType(scope, name, file, line, SizeInBits, - AlignInBits, offsetInBits, flags, debugType); + return DBuilder.createMemberType(Scope, Name, File, Line, SizeInBits, + 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( @@ -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,34 +1089,47 @@ } } + 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; } void CGDebugInfo::CollectRecordNormalField( - const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit, - SmallVectorImpl &elements, llvm::DIType *RecordTy, + const FieldDecl *Field, uint64_t OffsetInBits, llvm::DIFile *TUnit, + SmallVectorImpl &Elements, llvm::DIType *RecordTy, const RecordDecl *RD) { - StringRef name = field->getName(); - QualType type = field->getType(); + 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()) + if (Name.empty() && !Type->isRecordType()) return; llvm::DIType *FieldType; - if (field->isBitField()) { - FieldType = createBitFieldType(field, RecordTy, RD); + if (Field->isBitField()) { + 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); + Elements.push_back(FieldType); } void CGDebugInfo::CollectRecordNestedRecord( @@ -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); + FieldTy = + DBuilder.createMemberType(Unit, VD->getName(), Unit, 0, FieldSize, + 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 @@ -3271,8 +3341,9 @@ auto *D = ArgNo ? DBuilder.createParameterVariable(Scope, VD->getName(), *ArgNo, Unit, Line, Ty) - : DBuilder.createAutoVariable(Scope, VD->getName(), Unit, - Line, Ty); + : DBuilder.createAutoVariable( + Scope, VD->getName(), Unit, Line, Ty, + /* AlwaysPreserve */ false, AlignInBits, Flags); // Insert an llvm.dbg.declare into the current block. DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr), @@ -3304,7 +3375,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), @@ -3315,13 +3386,13 @@ } // Create the descriptor for the variable. - auto *D = - ArgNo - ? DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, - Ty, CGM.getLangOpts().Optimize, - Flags) - : DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty, - CGM.getLangOpts().Optimize, Flags); + auto *D = ArgNo + ? DBuilder.createParameterVariable( + Scope, Name, *ArgNo, Unit, Line, Ty, + CGM.getLangOpts().Optimize, Flags) + : DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty, + CGM.getLangOpts().Optimize, + AlignInBits, Flags); // Insert an llvm.dbg.declare into the current block. DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr), @@ -3374,6 +3445,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 +3481,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 +3694,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 +3720,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 +3745,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 +3792,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) {