]> granicus.if.org Git - clang/commitdiff
Better handling of the aligned attribute.
authorAnders Carlsson <andersca@mac.com>
Sat, 16 Feb 2008 19:51:27 +0000 (19:51 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 16 Feb 2008 19:51:27 +0000 (19:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47216 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ASTContext.cpp
Sema/SemaDecl.cpp
include/clang/AST/Attr.h
include/clang/Basic/DiagnosticKinds.def

index 7d7decb6ff0989111513ed7ee1f25fc48a35f4c3..def254ac46410c6def21df381173657f6592c8be 100644 (file)
@@ -319,6 +319,9 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D,
   unsigned RecordAlign = 8;  // Default alignment = 1 byte = 8 bits.
 
   if (D->getKind() != Decl::Union) {
+    if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+      RecordAlign = std::max(RecordAlign, AA->getAlignment());
+        
     bool StructIsPacked = D->getAttr<PackedAttr>();
     
     // Layout each field, for now, just sequentially, respecting alignment.  In
@@ -333,13 +336,26 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D,
         // query getTypeInfo about these, so we figure it out here.
         // Flexible array members don't have any size, but they
         // have to be aligned appropriately for their element type.
-        const ArrayType* ATy = FD->getType()->getAsArrayType();
-        FieldAlign = FieldIsPacked ? 8 : getTypeAlign(ATy->getElementType(), L);
+        
+        if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+          FieldAlign = AA->getAlignment();
+        else if (FieldIsPacked)
+          FieldAlign = 8;
+        else {
+          const ArrayType* ATy = FD->getType()->getAsArrayType();
+          FieldAlign = getTypeAlign(ATy->getElementType(), L);
+        }
         FieldSize = 0;
       } else {
         std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
         FieldSize = FieldInfo.first;
-        FieldAlign = FieldIsPacked ? 8 : FieldInfo.second;
+        
+        if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
+          FieldAlign = AA->getAlignment();
+        else if (FieldIsPacked)
+          FieldAlign = 8;
+        else
+          FieldAlign = FieldInfo.second;
       }
 
       // Round up the current record size to the field's alignment boundary.
index 61de36faf69d5547691b405a1db928bd2102e520..24013cd9dd0ebc8cd5bda920532e026d8443af12 100644 (file)
@@ -1835,8 +1835,8 @@ void Sema::HandleOCUVectorTypeAttribute(TypedefDecl *tDecl,
   Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
   llvm::APSInt vecSize(32);
   if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
-    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
-         sizeExpr->getSourceRange());
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_argument_not_int,
+         "ocu_vector_type", sizeExpr->getSourceRange());
     return;
   }
   // unlike gcc's vector_size attribute, we do not allow vectors to be defined
@@ -1873,8 +1873,8 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType,
   Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
   llvm::APSInt vecSize(32);
   if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
-    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
-         sizeExpr->getSourceRange());
+    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_argument_not_int,
+         "vector_size", sizeExpr->getSourceRange());
     return QualType();
   }
   // navigate to the base type - we need to provide for vector pointers, 
@@ -1959,15 +1959,24 @@ void Sema::HandleAlignedAttribute(Decl *d, AttributeList *rawAttr)
     return;
   }
 
-  // TODO: We probably need to actually do something with aligned attribute.
-  if (rawAttr->getNumArgs() == 0)
+  unsigned Align = 0;
+  
+  if (rawAttr->getNumArgs() == 0) {
+    // FIXME: This should be the target specific maximum alignment.
+    // (For now we just use 128 bits which is the maximum on X86.
+    Align = 128;
     return;
+  } else {
+    Expr *alignmentExpr = static_cast<Expr *>(rawAttr->getArg(0));
+    llvm::APSInt alignment(32);
+    if (!alignmentExpr->isIntegerConstantExpr(alignment, Context)) {
+      Diag(rawAttr->getAttributeLoc(), diag::err_attribute_argument_not_int,
+           "aligned", alignmentExpr->getSourceRange());
+      return;
+    }
+    
+    Align = alignment.getZExtValue() * 8;
+  }
 
-  Expr *alignmentExpr = static_cast<Expr *>(rawAttr->getArg(0));
-  llvm::APSInt alignment(32);
-  if (!alignmentExpr->isIntegerConstantExpr(alignment, Context)) {
-    Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
-         alignmentExpr->getSourceRange());
-    return;
-  }    
+  d->addAttr(new AlignedAttr(Align));
 }
index c3390a021aa632b72d4a6e3808aa1df4ffd64446..96281a97c89d4ff8e1221ca39c11f33ac5a56caf 100644 (file)
@@ -65,6 +65,20 @@ public:
   }
   static bool classof(const PackedAttr *A) { return true; }
 };
+  
+class AlignedAttr : public Attr {
+  unsigned Alignment;
+public:
+  AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
+  
+  unsigned getAlignment() const { return Alignment; }
+  
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() == Aligned;
+  }
+  static bool classof(const AlignedAttr *A) { return true; }
+};
 
 }  // end namespace clang
 
index 198183918d189538ca30ece6cc11b4206cde13d2..b380b76d4c5ef3bac3857ef4745cb0a37f38ca34 100644 (file)
@@ -561,8 +561,8 @@ DIAG(err_attribute_wrong_number_arguments, ERROR,
      "attribute requires %0 argument(s)")
 DIAG(err_attribute_invalid_vector_type, ERROR,
      "invalid vector type '%0'")
-DIAG(err_attribute_vector_size_not_int, ERROR,
-     "vector_size requires integer constant")
+DIAG(err_attribute_argument_not_int, ERROR,
+     "'%0' attribute requires integer constant")
 DIAG(err_attribute_invalid_size, ERROR,
      "vector size not an integral multiple of component size")
 DIAG(err_attribute_zero_size, ERROR,