[cfe-commits] r39368 - in /cfe/cfe/trunk: AST/SemaExpr.cpp AST/Type.cpp Sema/SemaExpr.cpp include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:43:40 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:43:40 2007
New Revision: 39368
URL: http://llvm.org/viewvc/llvm-project?rev=39368&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Finish up Sema::ParseArraySubscriptExpr. This involved:
- adding a couple predicates to Type.h (isObjectType, isDerivedType).
- added a diagnostic for subscripting non-object types (e.g. void (*)()).
- pass the correct result type...a minor detail:-)
- added some spec references to Type.h
Modified:
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/AST/Type.cpp
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/AST/Type.h
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39368&r1=39367&r2=39368&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:40 2007
@@ -225,10 +225,10 @@
TypeRef t2 = ((Expr *)Idx)->getTypeRef();
assert(!t1.isNull() && "no type for array base expression");
- assert(!t1.isNull() && "no type for array index expression");
+ assert(!t2.isNull() && "no type for array index expression");
- // In C, the expression e1[e2] is by definition precisely equivalent to
- // the expression *((e1)+(e2)). This means the array "Base" may actually be
+ // 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.
@@ -242,10 +242,24 @@
} else
return Diag(LLoc, diag::err_typecheck_subscript_value);
- if (indexType->isIntegralType())
- return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, baseType);
- else
+ // C99 6.5.2.1p1
+ if (!indexType->isIntegralType())
return Diag(LLoc, diag::err_typecheck_subscript);
+
+ TypeRef resultType;
+ if (ArrayType *ary = dyn_cast<ArrayType>(baseType)) {
+ resultType = ary->getElementType();
+ } else if (PointerType *ary = dyn_cast<PointerType>(baseType)) {
+ 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()) {
+ std::string Name;
+ baseType->getAsString(Name);
+ Diag(LLoc, diag::err_typecheck_subscript_not_object, Name);
+ }
+ }
+ return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType);
}
Action::ExprResult Sema::
Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39368&r1=39367&r2=39368&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:43:40 2007
@@ -29,6 +29,20 @@
return false;
}
+bool Type::isObjectType() const {
+ if (isa<FunctionType>(CanonicalType))
+ return false;
+ else if (CanonicalType->isIncompleteType())
+ return false;
+ else
+ return true;
+}
+
+bool Type::isDerivedType() const {
+ return isPointerType() || isArrayType() || isFunctionType() ||
+ isStructureType() || isUnionType();
+}
+
bool Type::isFunctionType() const {
return isa<FunctionType>(CanonicalType) ? true : false;
}
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39368&r1=39367&r2=39368&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:40 2007
@@ -225,10 +225,10 @@
TypeRef t2 = ((Expr *)Idx)->getTypeRef();
assert(!t1.isNull() && "no type for array base expression");
- assert(!t1.isNull() && "no type for array index expression");
+ assert(!t2.isNull() && "no type for array index expression");
- // In C, the expression e1[e2] is by definition precisely equivalent to
- // the expression *((e1)+(e2)). This means the array "Base" may actually be
+ // 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.
@@ -242,10 +242,24 @@
} else
return Diag(LLoc, diag::err_typecheck_subscript_value);
- if (indexType->isIntegralType())
- return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, baseType);
- else
+ // C99 6.5.2.1p1
+ if (!indexType->isIntegralType())
return Diag(LLoc, diag::err_typecheck_subscript);
+
+ TypeRef resultType;
+ if (ArrayType *ary = dyn_cast<ArrayType>(baseType)) {
+ resultType = ary->getElementType();
+ } else if (PointerType *ary = dyn_cast<PointerType>(baseType)) {
+ 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()) {
+ std::string Name;
+ baseType->getAsString(Name);
+ Diag(LLoc, diag::err_typecheck_subscript_not_object, Name);
+ }
+ }
+ return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, resultType);
}
Action::ExprResult Sema::
Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39368&r1=39367&r2=39368&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:43:40 2007
@@ -183,28 +183,39 @@
bool isCanonical() const { return CanonicalType == this; }
Type *getCanonicalType() const { return CanonicalType; }
- /// Helper methods to distinguish type categories. All type predicates
- /// operate on the canonical type, ignoring typedefs.
- bool isIntegralType() const; // short/int/long, char, bool, enum { ... }
- bool isFloatingType() const; // float, double, long double, complex
- bool isArithmeticType() const; // integral + floating
- bool isScalarType() const; // arithmetic + pointers
- bool isAggregateType() const; // arrays, structures
+ /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
+ /// object types, function types, and incomplete types.
- /// FIXME: consider adding classes to complete the "isa" support.
- bool isVoidType() const;
+ /// isObjectType - types that fully describe objects. An object is a region
+ /// of memory that can be examined and stored into (H&S).
+ bool isObjectType() const;
+
+ /// isFunctionType - types that describe functions.
bool isFunctionType() const;
- bool isPointerType() const;
- bool isArrayType() const;
- bool isStructureType() const; // no isa<StructType>(t) support
- bool isUnionType() const; // no isa<UnionType>(t) support
-
- /// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
- /// - a type that can describe objects, but which lacks information needed to
+
+ /// isIncompleteType - Return true if this is an incomplete type.
+ /// A type that can describe objects, but which lacks information needed to
/// determine its size (e.g. void, or a fwd declared struct). Clients of this
/// routine will need to determine if the size is actually required.
bool isIncompleteType() const;
+ /// Helper methods to distinguish type categories. All type predicates
+ /// operate on the canonical type, ignoring typedefs.
+ bool isIntegralType() const; // C99 6.2.5p17 (int, char, bool, enum)
+ bool isFloatingType() const; // C99 6.2.5p11 (float, double, long double)
+ bool isArithmeticType() const; // C99 6.2.5p18 (integral + floating)
+ bool isVoidType() const; // C99 6.2.5p19
+
+ /// Derived types (C99 6.2.5p20). isFunctionType() is also a derived type.
+ bool isDerivedType() const;
+ bool isPointerType() const;
+ bool isArrayType() const;
+ bool isStructureType() const;
+ bool isUnionType() const;
+
+ bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
+ bool isAggregateType() const; // C99 6.2.5p21 (arrays, structures)
+
virtual void getAsString(std::string &InnerString) const = 0;
static bool classof(const Type *) { return true; }
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39368&r1=39367&r2=39368&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:40 2007
@@ -488,6 +488,8 @@
"subscripted value is neither array nor pointer")
DIAG(err_typecheck_subscript, ERROR,
"array subscript is not an integer")
+DIAG(err_typecheck_subscript_not_object, ERROR,
+ "illegal subscript of non-object type '%s'")
DIAG(err_typecheck_member_reference_structUnion, ERROR,
"member reference is not a structure or union")
DIAG(err_typecheck_member_reference_arrow, ERROR,
More information about the cfe-commits
mailing list