[cfe-commits] r70497 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/AST/ExprConstant.cpp test/Sema/attr-aligned.c

Douglas Gregor dgregor at apple.com
Thu Apr 30 10:32:17 PDT 2009


Author: dgregor
Date: Thu Apr 30 12:32:17 2009
New Revision: 70497

URL: http://llvm.org/viewvc/llvm-project?rev=70497&view=rev
Log:
Properly compute the alignment of typedefs that make use of the
"aligned" attribute. Previously, we were skipping over these
attributes when we jumped directly to the canonical type. Now,
ASTContext::getTypeInfo walks through typedefs and other
"non-canonical" types manually, looking for "aligned" attributes on
typedefs.

As part of this change, I moved the GNU-specific logic (such as
determining the alignment of void or of a function pointer) out of the
expression evaluator and into ASTContext::getTypeInfo.



Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/Sema/attr-aligned.c

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=70497&r1=70496&r2=70497&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Apr 30 12:32:17 2009
@@ -334,24 +334,30 @@
 /// does not work on incomplete types.
 std::pair<uint64_t, unsigned>
 ASTContext::getTypeInfo(const Type *T) {
-  T = getCanonicalType(T);
   uint64_t Width=0;
   unsigned Align=8;
   switch (T->getTypeClass()) {
 #define TYPE(Class, Base)
 #define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base)
 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
 #include "clang/AST/TypeNodes.def"
-    assert(false && "Should not see non-canonical or dependent types");
+    assert(false && "Should not see dependent types");
     break;
 
   case Type::FunctionNoProto:
   case Type::FunctionProto:
+    // GCC extension: alignof(function) = 32 bits
+    Width = 0;
+    Align = 32;
+    break;
+
   case Type::IncompleteArray:
-    assert(0 && "Incomplete types have no size!");
   case Type::VariableArray:
-    assert(0 && "VLAs not implemented yet!");
+    Width = 0;
+    Align = getTypeAlign(cast<ArrayType>(T)->getElementType());
+    break;
+
   case Type::ConstantArray: {
     const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
     
@@ -377,7 +383,11 @@
     switch (cast<BuiltinType>(T)->getKind()) {
     default: assert(0 && "Unknown builtin type!");
     case BuiltinType::Void:
-      assert(0 && "Incomplete types have no size!");
+      // GCC extension: alignof(void) = 8 bits.
+      Width = 0;
+      Align = 8;
+      break;
+
     case BuiltinType::Bool:
       Width = Target.getBoolWidth();
       Align = Target.getBoolAlign();
@@ -517,10 +527,34 @@
     break;
   }
 
-  case Type::TemplateSpecialization:
-    assert(false && "Dependent types have no size");
+  case Type::Typedef: {
+    const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
+    if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
+      Align = Aligned->getAlignment();
+      Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
+    } else
+      return getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
     break;
   }
+
+  case Type::TypeOfExpr:
+    return getTypeInfo(cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType()
+                         .getTypePtr());
+
+  case Type::TypeOf:
+    return getTypeInfo(cast<TypeOfType>(T)->getUnderlyingType().getTypePtr());
+
+  case Type::QualifiedName:
+    return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
+    
+  case Type::TemplateSpecialization:
+    assert(getCanonicalType(T) != T && 
+           "Cannot request the size of a dependent type");
+    // FIXME: this is likely to be wrong once we support template
+    // aliases, since a template alias could refer to a typedef that
+    // has an __aligned__ attribute on it.
+    return getTypeInfo(getCanonicalType(T));
+  }
   
   assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
   return std::make_pair(Width, Align);

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=70497&r1=70496&r2=70497&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Apr 30 12:32:17 2009
@@ -1021,32 +1021,11 @@
 }
 
 unsigned IntExprEvaluator::GetAlignOfType(QualType T) {
-  const Type *Ty = Info.Ctx.getCanonicalType(T).getTypePtr();
-  
-  // __alignof__(void) = 1 as a gcc extension.
-  if (Ty->isVoidType())
-    return 1;
-
-  // GCC extension: alignof(function) = 4.
-  // FIXME: AlignOf shouldn't be unconditionally 4!  It should listen to the
-  // attribute(align) directive.
-  if (Ty->isFunctionType())
-    return 4;
-
-  if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(Ty))
-    return GetAlignOfType(QualType(EXTQT->getBaseType(), 0));
-
-  // alignof VLA/incomplete array.
-  if (const ArrayType *VAT = dyn_cast<ArrayType>(Ty))
-    return GetAlignOfType(VAT->getElementType());
-
-  // sizeof (objc class)?
-  if (isa<ObjCInterfaceType>(Ty))
-    return 1;  // FIXME: This probably isn't right.
-
   // Get information about the alignment.
   unsigned CharSize = Info.Ctx.Target.getCharWidth();
-  return Info.Ctx.getPreferredTypeAlign(Ty) / CharSize;
+
+  // FIXME: Why do we ask for the preferred alignment?
+  return Info.Ctx.getPreferredTypeAlign(T.getTypePtr()) / CharSize;
 }
 
 unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) {

Modified: cfe/trunk/test/Sema/attr-aligned.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-aligned.c?rev=70497&r1=70496&r2=70497&view=diff

==============================================================================
--- cfe/trunk/test/Sema/attr-aligned.c (original)
+++ cfe/trunk/test/Sema/attr-aligned.c Thu Apr 30 12:32:17 2009
@@ -5,3 +5,17 @@
 // PR3254
 short g0[3] __attribute__((aligned));
 short g0_chk[__alignof__(g0) == 16 ? 1 : -1]; 
+
+// <rdar://problem/6840045>
+typedef char ueber_aligned_char __attribute__((aligned(8)));
+
+struct struct_with_ueber_char {
+  ueber_aligned_char c;
+};
+
+char c = 0;
+
+char a0[__alignof__(ueber_aligned_char) == 8? 1 : -1] = { 0 };
+char a1[__alignof__(struct struct_with_ueber_char) == 8? 1 : -1] = { 0 };
+char a2[__alignof__(c) == 1? : -1] = { 0 };
+char a3[sizeof(c) == 1? : -1] = { 0 };





More information about the cfe-commits mailing list