forked from OSchip/llvm-project
Improve handling of alignof. alignof(VLA) now works properly for example.
llvm-svn: 62932
This commit is contained in:
parent
7bf46469f3
commit
24aeeab05c
|
@ -508,6 +508,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool HandleCast(CastExpr* E);
|
bool HandleCast(CastExpr* E);
|
||||||
|
uint64_t GetAlignOfExpr(const Expr *E);
|
||||||
|
uint64_t GetAlignOfType(QualType T);
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
@ -842,6 +844,41 @@ bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) {
|
||||||
return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
|
return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t IntExprEvaluator::GetAlignOfType(QualType T) {
|
||||||
|
const Type *Ty = Info.Ctx.getCanonicalType(T).getTypePtr();
|
||||||
|
|
||||||
|
// __alignof__(void) = 1 as a gcc extension.
|
||||||
|
if (Ty->isVoidType())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// GCC extension: alignof(function) = 4.
|
||||||
|
// FIXME: AlignOf shouldn't be unconditionally 4! It should listen to the
|
||||||
|
// attribute(align) directive.
|
||||||
|
if (Ty->isFunctionType())
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
if (const ASQualType *ASQT = dyn_cast<ASQualType>(Ty))
|
||||||
|
return GetAlignOfType(QualType(ASQT->getBaseType(), 0));
|
||||||
|
|
||||||
|
// alignof VLA/incomplete array.
|
||||||
|
if (const ArrayType *VAT = dyn_cast<ArrayType>(Ty))
|
||||||
|
return GetAlignOfType(VAT->getElementType());
|
||||||
|
|
||||||
|
// sizeof (objc class)?
|
||||||
|
if (isa<ObjCInterfaceType>(Ty))
|
||||||
|
return 1; // FIXME: This probably isn't right.
|
||||||
|
|
||||||
|
// Get information about the alignment.
|
||||||
|
unsigned CharSize = Info.Ctx.Target.getCharWidth();
|
||||||
|
return Info.Ctx.getTypeAlign(Ty) / CharSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
|
||||||
|
|
||||||
|
return GetAlignOfType(E->getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
|
/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the
|
||||||
/// expression's type.
|
/// expression's type.
|
||||||
bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
|
bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
|
||||||
|
@ -850,6 +887,15 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
|
||||||
Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
|
Result.zextOrTrunc(getIntTypeSizeInBits(DstTy));
|
||||||
Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
|
Result.setIsUnsigned(DstTy->isUnsignedIntegerType());
|
||||||
|
|
||||||
|
// Handle alignof separately.
|
||||||
|
if (!E->isSizeOf()) {
|
||||||
|
if (E->isArgumentType())
|
||||||
|
Result = GetAlignOfType(E->getArgumentType());
|
||||||
|
else
|
||||||
|
Result = GetAlignOfExpr(E->getArgumentExpr());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QualType SrcTy = E->getTypeOfArgument();
|
QualType SrcTy = E->getTypeOfArgument();
|
||||||
|
|
||||||
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
// sizeof(void) and __alignof__(void) = 1 as a gcc extension.
|
||||||
|
@ -859,31 +905,22 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
|
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
|
||||||
// FIXME: But alignof(vla) is!
|
if (!SrcTy->isConstantSizeType())
|
||||||
if (!SrcTy->isConstantSizeType()) {
|
|
||||||
// FIXME: Should we attempt to evaluate this?
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// sizeof (objc class) ?
|
// sizeof (objc class) ?
|
||||||
if (SrcTy->isObjCInterfaceType())
|
if (SrcTy->isObjCInterfaceType())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool isSizeOf = E->isSizeOf();
|
|
||||||
|
|
||||||
// GCC extension: sizeof(function) = 1.
|
// GCC extension: sizeof(function) = 1.
|
||||||
if (SrcTy->isFunctionType()) {
|
if (SrcTy->isFunctionType()) {
|
||||||
// FIXME: AlignOf shouldn't be unconditionally 4!
|
Result = 1;
|
||||||
Result = isSizeOf ? 1 : 4;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get information about the size or align.
|
// Get information about the size.
|
||||||
unsigned CharSize = Info.Ctx.Target.getCharWidth();
|
unsigned CharSize = Info.Ctx.Target.getCharWidth();
|
||||||
if (isSizeOf)
|
Result = Info.Ctx.getTypeSize(SrcTy) / CharSize;
|
||||||
Result = Info.Ctx.getTypeSize(SrcTy) / CharSize;
|
|
||||||
else
|
|
||||||
Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue