From af707ab8fbb9451e8febb8d766f6c043628125c4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 21:53:27 +0000 Subject: [PATCH] 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 --- include/clang/AST/ASTContext.h | 5 +++++ lib/AST/ASTContext.cpp | 20 ++++++++++++++++++++ lib/AST/ExprConstant.cpp | 19 ++++++++++++++----- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 9ac6027570..927d65b99f 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -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. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f3243c25ae..63e4ccc241 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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(D)) { + QualType T = VD->getType(); + // Incomplete or function types default to 1. + if (T->isIncompleteType() || T->isFunctionType()) + return 1; + + while (isa(T) || isa(T)) + T = cast(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. diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 6d1d150c1c..49cc3201db 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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(E)) + return Info.Ctx.getDeclAlign(DRE->getDecl()); + + if (const MemberExpr *ME = dyn_cast(E)) + return Info.Ctx.getDeclAlign(ME->getMemberDecl()); + return GetAlignOfType(E->getType()); } -- 2.40.0