vleschuk created this revision.
vleschuk added reviewers: echristo, aprantl, dblaikie, mehdi_amini.
vleschuk added a subscriber: cfe-commits.
Herald added a subscriber: mehdi_amini.

Add llvm::DINode::FlagAlignment to entities marked with C++11 'alignas', C11 
'_Alignas' keywords or ObjC clang attribute((aligned (N))).

https://reviews.llvm.org/D24426

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h

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<AlignedAttr>())
+        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<AlignedAttr>()) {
+    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<llvm::Metadata *> &elements, llvm::DIType *RecordTy,
+    const FieldDecl *Field, uint64_t OffsetInBits, llvm::DIFile *TUnit,
+    SmallVectorImpl<llvm::Metadata *> &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<AlignedAttr>()) {
+    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<AlignedAttr>())
+    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<AlignedAttr>())
+      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<AlignedAttr>())
+      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<AlignedAttr>())
+    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<AlignedAttr>())
+    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<AlignedAttr>()) {
+    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<VarDecl>(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<AlignedAttr>())
+    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<int64_t, 9> Expr;
+  uint64_t AlignInBits = 0;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (VD->isImplicit())
     Flags |= llvm::DINode::FlagArtificial;
+  if (VD->hasAttr<AlignedAttr>()) {
+    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<AlignedAttr>()) {
+    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<llvm::DILocalScope>(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<AlignedAttr>()) {
+    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<AlignedAttr>()) {
+    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) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to