Improvements to ASTContext::getDeclAlignInBytes; fixes the testcase in 
PR3254 and part of PR3433.

The isICE changes are necessary to keep the computed results 
consistent with Evaluate.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65258 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 181ea90..fce2289 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -264,21 +264,23 @@
 /// specified decl.  Note that bitfields do not have a valid alignment, so
 /// this method will assert on them.
 unsigned ASTContext::getDeclAlignInBytes(const Decl *D) {
-  // FIXME: If attribute(align) is specified on the decl, round up to it.
-  
+  unsigned Align = Target.getCharWidth();
+
+  if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
+    Align = std::max(Align, AA->getAlignment());
+
   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
     QualType T = VD->getType();
     // Incomplete or function types default to 1.
-    if (T->isIncompleteType() || T->isFunctionType())
-      return 1;
-    
-    while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
-      T = cast<ArrayType>(T)->getElementType();
-    
-    return getTypeAlign(T) / Target.getCharWidth();
+    if (!T->isIncompleteType() && !T->isFunctionType()) {
+      while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T))
+        T = cast<ArrayType>(T)->getElementType();
+
+      Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
+    }
   }
-  
-  return 1;
+
+  return Align / Target.getCharWidth();
 }
 
 /// getTypeSize - Return the size of the specified type, in bits.  This method