From: Steve Naroff Date: Thu, 30 Aug 2007 18:10:14 +0000 (+0000) Subject: Polish yesterday's Array/ConstantArray/VariableArray rewrite, removing a couple FIXME's. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9406125e2cac9208098655ac8058c095c2c3a65;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41616 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 57c1c44dbe..6a852950a7 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -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 diff --git a/AST/Type.cpp b/AST/Type.cpp index c0c278d19e..126f3d5db9 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -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()) { diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index 3bc0e760ba..d1d62a6ea2 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -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 || diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 372109a8f8..b1c71ac98c 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -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. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 58b3f4af51..a8fb40699b 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -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;