]> granicus.if.org Git - clang/commitdiff
add initial support for the gcc "alignof(decl) is the alignment of the decl
authorChris Lattner <sabre@nondot.org>
Sat, 24 Jan 2009 21:53:27 +0000 (21:53 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 24 Jan 2009 21:53:27 +0000 (21:53 +0000)
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

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/AST/ExprConstant.cpp

index 9ac6027570f3efc04121f3a5b50ae6da15a805db..927d65b99f522a1e40f215a85c0e4d483cfe8a86 100644 (file)
@@ -403,6 +403,11 @@ public:
     return getTypeInfo(T).second;
   }
   
+  /// getDeclAlign - Return a conservative estimate of the alignment of the
+  /// specified decl.  Note that bitfields do not have a valid alignment, so
+  /// this method will assert on them.
+  unsigned getDeclAlign(const Decl *D);
+  
   /// getASTRecordLayout - Get or compute information about the layout of the
   /// specified record (struct/union/class), which indicates its size and field
   /// position information.
index f3243c25ae71e2c2438b06248f56acf15a827785..63e4ccc24157b04e1bdbe974303cc5b79d43a168 100644 (file)
@@ -260,6 +260,26 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
   }
 }
 
+/// getDeclAlign - Return a conservative estimate of the alignment of the
+/// specified decl.  Note that bitfields do not have a valid alignment, so
+/// this method will assert on them.
+unsigned ASTContext::getDeclAlign(const Decl *D) {
+  // FIXME: If attribute(align) is specified on the decl, round up to it.
+  
+  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);
+  }
+  
+  return 1;
+}
 
 /// getTypeSize - Return the size of the specified type, in bits.  This method
 /// does not work on incomplete types.
index 6d1d150c1c165f78ec74cfc45a93fec4993d6729..49cc3201db974af205ded708e5f7cfdc0a173e22 100644 (file)
@@ -508,8 +508,8 @@ public:
 
 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 @@ bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
   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 @@ uint64_t IntExprEvaluator::GetAlignOfType(QualType T) {
   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());
 }