summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
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