From: Chris Lattner Date: Sat, 24 Jan 2009 21:53:27 +0000 (+0000) Subject: add initial support for the gcc "alignof(decl) is the alignment of the decl X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af707ab8fbb9451e8febb8d766f6c043628125c4;p=clang 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 --- 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()); }