summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-01-24 21:53:27 +0000
committerChris Lattner <sabre@nondot.org>2009-01-24 21:53:27 +0000
commit6806131c6b23a389ac75681e9b396316e097e31f (patch)
tree87ad67a9a1ecbd38d7151f53f58dfa74928e215f /clang/lib/AST
parent2b3389a626efcf3758c14698bb0caea68edf8e27 (diff)
downloadbcm5719-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.cpp20
-rw-r--r--clang/lib/AST/ExprConstant.cpp19
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());
}
OpenPOWER on IntegriCloud