From: Anders Carlsson Date: Sat, 16 Feb 2008 19:51:27 +0000 (+0000) Subject: Better handling of the aligned attribute. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=042c4e7e9f0b54104f4f2e098c028aa8247b6bed;p=clang Better handling of the aligned attribute. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47216 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 7d7decb6ff..def254ac46 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -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()) + RecordAlign = std::max(RecordAlign, AA->getAlignment()); + bool StructIsPacked = D->getAttr(); // 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()) + 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 FieldInfo = getTypeInfo(FD->getType(), L); FieldSize = FieldInfo.first; - FieldAlign = FieldIsPacked ? 8 : FieldInfo.second; + + if (const AlignedAttr *AA = FD->getAttr()) + FieldAlign = AA->getAlignment(); + else if (FieldIsPacked) + FieldAlign = 8; + else + FieldAlign = FieldInfo.second; } // Round up the current record size to the field's alignment boundary. diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 61de36faf6..24013cd9dd 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1835,8 +1835,8 @@ void Sema::HandleOCUVectorTypeAttribute(TypedefDecl *tDecl, Expr *sizeExpr = static_cast(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(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(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(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)); } diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index c3390a021a..96281a97c8 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -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 diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 198183918d..b380b76d4c 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -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,