diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-01-24 21:53:27 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-01-24 21:53:27 +0000 |
| commit | 6806131c6b23a389ac75681e9b396316e097e31f (patch) | |
| tree | 87ad67a9a1ecbd38d7151f53f58dfa74928e215f /clang/lib/AST | |
| parent | 2b3389a626efcf3758c14698bb0caea68edf8e27 (diff) | |
| download | bcm5719-llvm-6806131c6b23a389ac75681e9b396316e097e31f.tar.gz bcm5719-llvm-6806131c6b23a389ac75681e9b396316e097e31f.zip | |
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.
llvm-svn: 62939
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 20 | ||||
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 19 |
2 files changed, 34 insertions, 5 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f3243c25ae7..63e4ccc2415 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/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<ValueDecl>(D)) { + QualType T = VD->getType(); + // Incomplete or function types default to 1. + if (T->isIncompleteType() || T->isFunctionType()) + return 1; + + while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T)) + T = cast<ArrayType>(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/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6d1d150c1c1..49cc3201db9 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/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<DeclRefExpr>(E)) + return Info.Ctx.getDeclAlign(DRE->getDecl()); + + if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) + return Info.Ctx.getDeclAlign(ME->getMemberDecl()); + return GetAlignOfType(E->getType()); } |

