forked from OSchip/llvm-project
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:
parent
68ebef886a
commit
36d572b9ea
|
@ -280,54 +280,53 @@ Action::ExprResult Sema::
|
||||||
ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
|
ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
|
||||||
ExprTy *Idx, SourceLocation RLoc) {
|
ExprTy *Idx, SourceLocation RLoc) {
|
||||||
Expr *LHSExp = static_cast<Expr*>(Base), *RHSExp = static_cast<Expr*>(Idx);
|
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");
|
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
|
// 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
|
// 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
|
// in the subscript position. As a result, we need to derive the array base
|
||||||
// and index from the expression types.
|
// and index from the expression types.
|
||||||
|
Expr *BaseExpr, *IndexExpr;
|
||||||
Expr *baseExpr, *indexExpr;
|
QualType ResultType;
|
||||||
QualType baseType, indexType;
|
if (PointerType *PTy = LHSTy->isPointerType()) {
|
||||||
if (isa<PointerType>(canonT1) || isa<VectorType>(canonT1)) {
|
BaseExpr = LHSExp;
|
||||||
baseType = canonT1;
|
IndexExpr = RHSExp;
|
||||||
indexType = canonT2;
|
// FIXME: need to deal with const...
|
||||||
baseExpr = LHSExp;
|
ResultType = PTy->getPointeeType();
|
||||||
indexExpr = RHSExp;
|
} else if (PointerType *PTy = RHSTy->isPointerType()) { // uncommon: 123[Ptr]
|
||||||
} else if (isa<PointerType>(canonT2)) { // uncommon
|
BaseExpr = RHSExp;
|
||||||
baseType = canonT2;
|
IndexExpr = LHSExp;
|
||||||
indexType = canonT1;
|
// FIXME: need to deal with const...
|
||||||
baseExpr = RHSExp;
|
ResultType = PTy->getPointeeType();
|
||||||
indexExpr = LHSExp;
|
} else if (VectorType *VTy = LHSTy->isVectorType()) { // vectors: V[123]
|
||||||
|
BaseExpr = LHSExp;
|
||||||
|
IndexExpr = RHSExp;
|
||||||
|
// FIXME: need to deal with const...
|
||||||
|
ResultType = VTy->getElementType();
|
||||||
} else {
|
} else {
|
||||||
return Diag(LHSExp->getLocStart(), diag::err_typecheck_subscript_value,
|
return Diag(LHSExp->getLocStart(), diag::err_typecheck_subscript_value,
|
||||||
RHSExp->getSourceRange());
|
RHSExp->getSourceRange());
|
||||||
}
|
}
|
||||||
// C99 6.5.2.1p1
|
// C99 6.5.2.1p1
|
||||||
if (!indexType->isIntegerType()) {
|
if (!IndexExpr->getType()->isIntegerType())
|
||||||
return Diag(indexExpr->getLocStart(), diag::err_typecheck_subscript,
|
return Diag(IndexExpr->getLocStart(), diag::err_typecheck_subscript,
|
||||||
indexExpr->getSourceRange());
|
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();
|
|
||||||
|
|
||||||
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::
|
Action::ExprResult Sema::
|
||||||
|
|
Loading…
Reference in New Issue