Use the return value of isPointerType and isVectorType to significantly simplify

ParseArraySubscriptExpr.  Notably, the new code doesn't have to think about 
canonical types at all.

llvm-svn: 39891
This commit is contained in:
Chris Lattner 2007-07-16 00:14:47 +00:00
parent 68ebef886a
commit 36d572b9ea
1 changed files with 34 additions and 35 deletions

View File

@ -280,54 +280,53 @@ Action::ExprResult Sema::
ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
ExprTy *Idx, SourceLocation RLoc) {
Expr *LHSExp = static_cast<Expr*>(Base), *RHSExp = static_cast<Expr*>(Idx);
QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
// Perform default conversions.
DefaultFunctionArrayConversion(LHSExp);
DefaultFunctionArrayConversion(RHSExp);
QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
assert(!LHSTy.isNull() && !RHSTy.isNull() && "missing types");
QualType canonT1 = DefaultFunctionArrayConversion(LHSExp).getCanonicalType();
QualType canonT2 = DefaultFunctionArrayConversion(RHSExp).getCanonicalType();
// C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent
// to the expression *((e1)+(e2)). This means the array "Base" may actually be
// in the subscript position. As a result, we need to derive the array base
// and index from the expression types.
Expr *baseExpr, *indexExpr;
QualType baseType, indexType;
if (isa<PointerType>(canonT1) || isa<VectorType>(canonT1)) {
baseType = canonT1;
indexType = canonT2;
baseExpr = LHSExp;
indexExpr = RHSExp;
} else if (isa<PointerType>(canonT2)) { // uncommon
baseType = canonT2;
indexType = canonT1;
baseExpr = RHSExp;
indexExpr = LHSExp;
Expr *BaseExpr, *IndexExpr;
QualType ResultType;
if (PointerType *PTy = LHSTy->isPointerType()) {
BaseExpr = LHSExp;
IndexExpr = RHSExp;
// FIXME: need to deal with const...
ResultType = PTy->getPointeeType();
} else if (PointerType *PTy = RHSTy->isPointerType()) { // uncommon: 123[Ptr]
BaseExpr = RHSExp;
IndexExpr = LHSExp;
// FIXME: need to deal with const...
ResultType = PTy->getPointeeType();
} else if (VectorType *VTy = LHSTy->isVectorType()) { // vectors: V[123]
BaseExpr = LHSExp;
IndexExpr = RHSExp;
// FIXME: need to deal with const...
ResultType = VTy->getElementType();
} else {
return Diag(LHSExp->getLocStart(), diag::err_typecheck_subscript_value,
RHSExp->getSourceRange());
}
// C99 6.5.2.1p1
if (!indexType->isIntegerType()) {
return Diag(indexExpr->getLocStart(), diag::err_typecheck_subscript,
indexExpr->getSourceRange());
}
QualType resultType;
if (PointerType *ary = dyn_cast<PointerType>(baseType)) {
// FIXME: need to deal with const...
resultType = ary->getPointeeType();
// in practice, the following check catches trying to index a pointer
// to a function (e.g. void (*)(int)). Functions are not objects in c99.
if (!resultType->isObjectType()) {
return Diag(baseExpr->getLocStart(),
diag::err_typecheck_subscript_not_object,
baseType.getAsString(), baseExpr->getSourceRange());
}
} else if (VectorType *vec = dyn_cast<VectorType>(baseType))
resultType = vec->getElementType();
if (!IndexExpr->getType()->isIntegerType())
return Diag(IndexExpr->getLocStart(), diag::err_typecheck_subscript,
IndexExpr->getSourceRange());
return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType, RLoc);
// C99 6.5.2.1p1: "shall have type "pointer to *object* type". In practice,
// the following check catches trying to index a pointer to a function (e.g.
// void (*)(int)). Functions are not objects in C99.
if (!ResultType->isObjectType())
return Diag(BaseExpr->getLocStart(),
diag::err_typecheck_subscript_not_object,
BaseExpr->getType().getAsString(), BaseExpr->getSourceRange());
return new ArraySubscriptExpr(LHSExp, RHSExp, ResultType, RLoc);
}
Action::ExprResult Sema::