Polish yesterday's Array/ConstantArray/VariableArray rewrite, removing a couple FIXME's.

Refactored Array/VariableArray, moving SizeModifier/IndexTypeQuals back up to Array. These
attributes are not specific to VLA's. Most of them are specific to array parameter types.

llvm-svn: 41616
This commit is contained in:
Steve Naroff 2007-08-30 18:10:14 +00:00
parent 98dbf0a3b8
commit 90dfdd5774
5 changed files with 52 additions and 47 deletions

View File

@ -404,7 +404,9 @@ QualType ASTContext::getReferenceType(QualType T) {
/// getConstantArrayType - Return the unique reference to the type for an
/// array of the specified element type.
QualType ASTContext::getConstantArrayType(QualType EltTy,
const llvm::APInt &ArySize) {
const llvm::APInt &ArySize,
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals) {
llvm::FoldingSetNodeID ID;
ConstantArrayType::Profile(ID, EltTy, ArySize);
@ -416,14 +418,15 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
// so fill in the canonical type field.
QualType Canonical;
if (!EltTy->isCanonical()) {
Canonical = getConstantArrayType(EltTy.getCanonicalType(), ArySize);
Canonical = getConstantArrayType(EltTy.getCanonicalType(), ArySize,
ASM, EltTypeQuals);
// Get the new insert position for the node we care about.
ConstantArrayType *NewIP = ArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(NewIP == 0 && "Shouldn't be in the map!");
}
ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize);
ConstantArrayType *New = new ConstantArrayType(EltTy, Canonical, ArySize,
ASM, EltTypeQuals);
ArrayTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
@ -432,22 +435,14 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
/// getArrayType - If NumElts is a constant expression, we return a unique
/// reference to an AST node of type ConstantArrayType. If NumElts is not
/// a constant expression, we return an instance of VaribleLengthArrayType.
QualType ASTContext::getArrayType(QualType EltTy,
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals, Expr *NumElts) {
llvm::APSInt ArySize(32);
// If no expression was provided, we consider it a VLA.
if (!NumElts || !NumElts->isIntegerConstantExpr(ArySize, *this)) {
// Since we don't unique expressions, it isn't possible to unique VLA's.
ArrayType *New = new VariableArrayType(EltTy, ASM, EltTypeQuals,
QualType(), NumElts);
Types.push_back(New);
return QualType(New, 0);
}
// Unique constant array types, to guarantee there is only one array of a
// particular structure.
// FIXME: should we warn if ASM != ArrayType::Normal or EltTypeQuals != 0?
return getConstantArrayType(EltTy, ArySize);
QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts,
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals) {
// Since we don't unique expressions, it isn't possible to unique VLA's.
ArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
ASM, EltTypeQuals);
Types.push_back(New);
return QualType(New, 0);
}
/// getVectorType - Return the unique reference to a vector type of

View File

@ -700,14 +700,14 @@ void ConstantArrayType::getAsStringInternal(std::string &S) const {
void VariableArrayType::getAsStringInternal(std::string &S) const {
S += '[';
if (IndexTypeQuals) {
AppendTypeQualList(S, IndexTypeQuals);
if (getIndexTypeQualifier()) {
AppendTypeQualList(S, getIndexTypeQualifier());
S += ' ';
}
if (SizeModifier == Static)
if (getSizeModifier() == Static)
S += "static";
else if (SizeModifier == Star)
else if (getSizeModifier() == Star)
S += '*';
if (getSizeExpr()) {

View File

@ -202,8 +202,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
D.setInvalidType(true);
}
}
T = Context.getArrayType(T, ASM, ATI.TypeQuals, ArraySize);
llvm::APSInt ConstVal(32);
// If no expression was provided, we consider it a VLA.
if (!ArraySize || !ArraySize->isIntegerConstantExpr(ConstVal, Context))
T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals);
else
T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals);
// If this is not C99, extwarn about VLA's and C99 array size modifiers.
if (!getLangOptions().C99 &&
(ASM != ArrayType::Normal ||

View File

@ -80,12 +80,15 @@ public:
/// getArrayType - If NumElts is a constant expression, we return a unique
/// reference to an AST node of type ConstantArrayType. If NumElts is not
/// a constant expression, we return an instance of VaribleLengthArrayType.
QualType getArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals, Expr *NumElts);
QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals);
/// getConstantArrayType - Return the unique reference to the type for an
/// array of the specified element type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &Sz);
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals);
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.

View File

@ -437,19 +437,30 @@ class ArrayType : public Type {
public:
/// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
/// an array with a static size (e.g. int X[static 4]), or with a star size
/// (e.g. int X[*]). FIXME: consider moving this down to VLAArayType.
/// (e.g. int X[*]). 'static' is only allowed on function parameters.
enum ArraySizeModifier {
Normal, Static, Star
};
private:
/// ElementType - The element type of the array.
QualType ElementType;
/// NOTE: These fields are packed into the bitfields space in the Type class.
ArraySizeModifier SizeModifier : 2;
/// IndexTypeQuals - Capture qualifiers in declarations like:
/// 'int X[static restrict 4]'. For function parameters only.
unsigned IndexTypeQuals : 3;
protected:
ArrayType(TypeClass tc, QualType et, QualType can)
: Type(tc, can), ElementType(et) {}
ArrayType(TypeClass tc, QualType et, QualType can,
ArraySizeModifier sm, unsigned tq)
: Type(tc, can), ElementType(et), SizeModifier(sm), IndexTypeQuals(tq) {}
friend class ASTContext; // ASTContext creates these.
public:
QualType getElementType() const { return ElementType; }
ArraySizeModifier getSizeModifier() const { return SizeModifier; }
unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
@ -461,8 +472,9 @@ public:
class ConstantArrayType : public ArrayType, public llvm::FoldingSetNode {
llvm::APInt Size; // Allows us to unique the type.
ConstantArrayType(QualType et, QualType can, llvm::APInt sz)
: ArrayType(ConstantArray, et, can), Size(sz) {}
ConstantArrayType(QualType et, QualType can, llvm::APInt sz,
ArraySizeModifier sm, unsigned tq)
: ArrayType(ConstantArray, et, can, sm, tq), Size(sz) {}
friend class ASTContext; // ASTContext creates these.
public:
llvm::APInt getSize() const { return Size; }
@ -485,25 +497,15 @@ public:
// FIXME: VariableArrayType's aren't uniqued (since expressions aren't).
class VariableArrayType : public ArrayType {
/// NOTE: These fields are packed into the bitfields space in the Type class.
ArraySizeModifier SizeModifier : 2;
/// IndexTypeQuals - Capture qualifiers in declarations like:
/// 'int X[static restrict 4]'.
unsigned IndexTypeQuals : 3;
/// SizeExpr - An assignment expression. VLA's are only permitted within
/// a function block.
Expr *SizeExpr;
VariableArrayType(QualType et, ArraySizeModifier sm, unsigned tq,
QualType can, Expr *e)
: ArrayType(VariableArray, et, can),
SizeModifier(sm), IndexTypeQuals(tq), SizeExpr(e) {}
VariableArrayType(QualType et, QualType can, Expr *e,
ArraySizeModifier sm, unsigned tq)
: ArrayType(VariableArray, et, can, sm, tq), SizeExpr(e) {}
friend class ASTContext; // ASTContext creates these.
public:
ArraySizeModifier getSizeModifier() const { return SizeModifier; }
unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
Expr *getSizeExpr() const { return SizeExpr; }
virtual void getAsStringInternal(std::string &InnerString) const;