forked from OSchip/llvm-project
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:
parent
98dbf0a3b8
commit
90dfdd5774
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue