forked from OSchip/llvm-project
Bug #:
Submitted by: Reviewed by: Added size expression to ArrayType. This was needed to implement Type::isIncompleteType(). At the moment, there is no support for determining if we have a constant expression (which won't be too difficult now that we have support for literal parsing/ast's). Nevertheless, the parser will allow "struct foo { int a[b]; }" (which is illegal). There is still significant work to fully analyze array types. The good news is "carbon.h" goes from 288 bogus errors down to 26! llvm-svn: 39355
This commit is contained in:
parent
4f88b3113e
commit
b7d4924eb1
|
@ -155,12 +155,10 @@ TypeRef ASTContext::getPointerType(TypeRef T) {
|
|||
/// specified element type.
|
||||
TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
|
||||
unsigned EltTypeQuals, Expr *NumElts) {
|
||||
#warning "IGNORING SIZE"
|
||||
|
||||
// Unique array types, to guarantee there is only one array of a particular
|
||||
// structure.
|
||||
FoldingSetNodeID ID;
|
||||
ArrayType::Profile(ID, ASM, EltTypeQuals, EltTy);
|
||||
ArrayType::Profile(ID, ASM, EltTypeQuals, EltTy, NumElts);
|
||||
|
||||
void *InsertPos = 0;
|
||||
if (ArrayType *ATP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
|
@ -178,7 +176,7 @@ TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
|
|||
assert(NewIP == 0 && "Shouldn't be in the map!");
|
||||
}
|
||||
|
||||
ArrayType *New = new ArrayType(EltTy, ASM, EltTypeQuals, Canonical);
|
||||
ArrayType *New = new ArrayType(EltTy, ASM, EltTypeQuals, Canonical, NumElts);
|
||||
ArrayTypes.InsertNode(New, InsertPos);
|
||||
Types.push_back(New);
|
||||
return New;
|
||||
|
|
|
@ -41,11 +41,16 @@ bool Type::isIncompleteType() const {
|
|||
// A tagged type (struct/union/enum/class) is incomplete if the decl is a
|
||||
// forward declaration, but not a full definition (C99 6.2.5p22).
|
||||
return !cast<TaggedType>(this)->getDecl()->isDefinition();
|
||||
|
||||
case Array:
|
||||
// An array of unknown size is an incomplete type (C99 6.2.5p22).
|
||||
// FIXME: Implement this.
|
||||
return true; // cast<ArrayType>(this)-> blah.
|
||||
// In C99, an unknown size is permitted in 4 instances:
|
||||
// - The array being declared is a formal parameter of a function.
|
||||
// - The declarator is accompanied by an initializer from which the array
|
||||
// can be deduced (char foo[] = "whatever").
|
||||
// - Forward declarations (extern int matrix[][7]).
|
||||
// - The last component of a structure (flexible array idiom).
|
||||
// Clients of this routine will need to determine if the size is required.
|
||||
return cast<ArrayType>(this)->getSizeExpression() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -473,7 +473,7 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
|
|||
// constant: integer-constant
|
||||
// constant: floating-constant
|
||||
|
||||
Actions.ParseNumericConstant(Tok);
|
||||
Res = Actions.ParseNumericConstant(Tok);
|
||||
ConsumeToken();
|
||||
|
||||
// These can be followed by postfix-expr pieces.
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace clang {
|
|||
class TagDecl;
|
||||
class RecordDecl;
|
||||
class EnumDecl;
|
||||
class Expr;
|
||||
|
||||
/// TypeRef - For efficiency, we don't store CVR-qualified types as nodes on
|
||||
/// their own: instead each reference to a type stores the qualifiers. This
|
||||
|
@ -267,29 +268,34 @@ private:
|
|||
/// ElementType - The element type of the array.
|
||||
TypeRef ElementType;
|
||||
|
||||
/// FIXME: Capture size for VLA or constant size.
|
||||
/// FIXME: Update Profile()!
|
||||
/// Use this to implement Type::isIncompleteType.
|
||||
|
||||
ArrayType(TypeRef et, ArraySizeModifier sm, unsigned tq, Type *can)
|
||||
: Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et) {}
|
||||
/// SizeExpr - The size is either a constant or assignment expression (for
|
||||
/// Variable Length Arrays). VLA's are only permitted within a function block.
|
||||
Expr *SizeExpr;
|
||||
|
||||
ArrayType(TypeRef et, ArraySizeModifier sm, unsigned tq, Type *can, Expr *e)
|
||||
: Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et),
|
||||
SizeExpr(e) {}
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
public:
|
||||
|
||||
TypeRef getElementType() const { return ElementType; }
|
||||
ArraySizeModifier getSizeModifier() const { return SizeModifier; }
|
||||
unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
|
||||
Expr *getSizeExpression() const { return SizeExpr; }
|
||||
|
||||
virtual void getAsString(std::string &InnerString) const;
|
||||
|
||||
void Profile(FoldingSetNodeID &ID) {
|
||||
Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType());
|
||||
Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType(),
|
||||
getSizeExpression());
|
||||
}
|
||||
static void Profile(FoldingSetNodeID &ID, ArraySizeModifier SizeModifier,
|
||||
unsigned IndexTypeQuals, TypeRef ElementType) {
|
||||
unsigned IndexTypeQuals, TypeRef ElementType,
|
||||
Expr *SizeExpr) {
|
||||
ID.AddInteger(SizeModifier);
|
||||
ID.AddInteger(IndexTypeQuals);
|
||||
ID.AddPointer(ElementType.getAsOpaquePtr());
|
||||
ID.AddPointer(SizeExpr);
|
||||
}
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == Array; }
|
||||
|
|
|
@ -253,7 +253,8 @@ struct DeclaratorChunk {
|
|||
bool isStar : 1;
|
||||
|
||||
/// This is the size of the array, or null if [] or [*] was specified.
|
||||
/// FIXME: make this be an expression* when we have expressions.
|
||||
/// Since the parser is multi-purpose, and we don't want to impose a root
|
||||
/// expression class on all clients, NumElts is untyped.
|
||||
void *NumElts;
|
||||
void destroy() {}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue