add initial support for the gcc "alignof(decl) is the alignment of the decl
not the type" semantics.  This can definitely be improved, but is better than
what we had.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62939 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 6d1d150..49cc320 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -508,8 +508,8 @@
 
 private:
   bool HandleCast(CastExpr* E);
-  uint64_t GetAlignOfExpr(const Expr *E);
-  uint64_t GetAlignOfType(QualType T);
+  unsigned GetAlignOfExpr(const Expr *E);
+  unsigned GetAlignOfType(QualType T);
 };
 } // end anonymous namespace
 
@@ -844,7 +844,7 @@
   return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
 }
 
-uint64_t IntExprEvaluator::GetAlignOfType(QualType T) {
+unsigned IntExprEvaluator::GetAlignOfType(QualType T) {
   const Type *Ty = Info.Ctx.getCanonicalType(T).getTypePtr();
   
   // __alignof__(void) = 1 as a gcc extension.
@@ -873,8 +873,17 @@
   return Info.Ctx.getTypeAlign(Ty) / CharSize;
 }
 
-uint64_t IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
-  
+unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
+  E = E->IgnoreParens();
+
+  // alignof decl is always accepted, even if it doesn't make sense: we default
+  // to 1 in those cases. 
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    return Info.Ctx.getDeclAlign(DRE->getDecl());
+    
+  if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
+    return Info.Ctx.getDeclAlign(ME->getMemberDecl());
+
   return GetAlignOfType(E->getType());
 }