diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 24 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 27 |
2 files changed, 20 insertions, 31 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 181ea90691..fce2289574 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -264,21 +264,23 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { /// specified decl. Note that bitfields do not have a valid alignment, so /// this method will assert on them. unsigned ASTContext::getDeclAlignInBytes(const Decl *D) { - // FIXME: If attribute(align) is specified on the decl, round up to it. - + unsigned Align = Target.getCharWidth(); + + if (const AlignedAttr* AA = D->getAttr<AlignedAttr>()) + Align = std::max(Align, AA->getAlignment()); + 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) / Target.getCharWidth(); + if (!T->isIncompleteType() && !T->isFunctionType()) { + while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T)) + T = cast<ArrayType>(T)->getElementType(); + + Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); + } } - - return 1; + + return Align / Target.getCharWidth(); } /// getTypeSize - Return the size of the specified type, in bits. This method diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index b613492f14..f27419c0a2 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -994,31 +994,18 @@ bool Expr::isIntegerConstantExprInternal(llvm::APSInt &Result, ASTContext &Ctx, } case SizeOfAlignOfExprClass: { const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(this); - QualType ArgTy = Exp->getTypeOfArgument(); - // sizeof(void) and __alignof__(void) = 1 as a gcc extension. - if (ArgTy->isVoidType()) { - Result = Ctx.MakeIntValue(1, getType()); - break; - } - - // alignof always evaluates to a constant, sizeof does if arg is not VLA. - if (Exp->isSizeOf() && !ArgTy->isConstantSizeType()) { + + // alignof is always an ICE; sizeof is an ICE if and only if + // the operand isn't a VLA + if (Exp->isSizeOf() && ArgTy->isVariableArrayType()) { if (Loc) *Loc = Exp->getOperatorLoc(); return false; } - // Get information about the size or align. - if (ArgTy->isFunctionType()) { - // GCC extension: sizeof(function) = 1. - Result = Ctx.MakeIntValue(Exp->isSizeOf() ? 1 : 4, getType()); - } else { - unsigned CharSize = Ctx.Target.getCharWidth(); - if (Exp->isSizeOf()) - Result = Ctx.MakeIntValue(Ctx.getTypeSize(ArgTy)/CharSize, getType()); - else - Result = Ctx.MakeIntValue(Ctx.getTypeAlign(ArgTy)/CharSize, getType()); - } + // Use the Evaluate logic to calculate the value, since the + // calculation is non-trivial. + Result = EvaluateAsInt(Ctx); break; } case BinaryOperatorClass: { |