ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals);
- /// getConstantArrayWithExprType - Return a reference to the type for a
- /// constant array of the specified element type.
- QualType getConstantArrayWithExprType(QualType EltTy,
- const llvm::APInt &ArySize,
- Expr *ArySizeExpr,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals,
- SourceRange Brackets);
-
- /// getConstantArrayWithoutExprType - Return a reference to the type
- /// for a constant array of the specified element type.
- QualType getConstantArrayWithoutExprType(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.
QualType getVectorType(QualType VectorType, unsigned NumElts);
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
};
-template<>
-struct CanProxyAdaptor<ConstantArrayWithExprType>
- : public CanProxyBase<ConstantArrayWithExprType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
-};
-
-template<>
-struct CanProxyAdaptor<ConstantArrayWithoutExprType>
- : public CanProxyBase<ConstantArrayWithoutExprType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
-};
-
template<>
struct CanProxyAdaptor<IncompleteArrayType>
: public CanProxyBase<IncompleteArrayType> {
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == ConstantArrayWithExpr ||
- T->getTypeClass() == ConstantArrayWithoutExpr ||
T->getTypeClass() == VariableArray ||
T->getTypeClass() == IncompleteArray ||
T->getTypeClass() == DependentSizedArray;
ID.AddInteger(TypeQuals);
}
static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == ConstantArrayWithExpr ||
- T->getTypeClass() == ConstantArrayWithoutExpr;
+ return T->getTypeClass() == ConstantArray;
}
static bool classof(const ConstantArrayType *) { return true; }
};
-/// ConstantArrayWithExprType - This class represents C arrays with a
-/// constant size specified by means of an integer constant expression.
-/// For example 'int A[sizeof(int)]' has ConstantArrayWithExprType where
-/// the element type is 'int' and the size expression is 'sizeof(int)'.
-/// These types are non-canonical.
-class ConstantArrayWithExprType : public ConstantArrayType {
- /// SizeExpr - The ICE occurring in the concrete syntax.
- Expr *SizeExpr;
- /// Brackets - The left and right array brackets.
- SourceRange Brackets;
-
- ConstantArrayWithExprType(QualType et, QualType can,
- const llvm::APInt &size, Expr *e,
- ArraySizeModifier sm, unsigned tq,
- SourceRange brackets)
- : ConstantArrayType(ConstantArrayWithExpr, et, can, size, sm, tq),
- SizeExpr(e), Brackets(brackets) {}
- friend class ASTContext; // ASTContext creates these.
- virtual void Destroy(ASTContext& C);
-
-public:
- Expr *getSizeExpr() const { return SizeExpr; }
- SourceRange getBracketsRange() const { return Brackets; }
- SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
- SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
-
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArrayWithExpr;
- }
- static bool classof(const ConstantArrayWithExprType *) { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- assert(0 && "Cannot unique ConstantArrayWithExprTypes.");
- }
-};
-
-/// ConstantArrayWithoutExprType - This class represents C arrays with a
-/// constant size that was not specified by an integer constant expression,
-/// but inferred by static semantics.
-/// For example 'int A[] = { 0, 1, 2 }' has ConstantArrayWithoutExprType.
-/// These types are non-canonical: the corresponding canonical type,
-/// having the size specified in an APInt object, is a ConstantArrayType.
-class ConstantArrayWithoutExprType : public ConstantArrayType {
-
- ConstantArrayWithoutExprType(QualType et, QualType can,
- const llvm::APInt &size,
- ArraySizeModifier sm, unsigned tq)
- : ConstantArrayType(ConstantArrayWithoutExpr, et, can, size, sm, tq) {}
- friend class ASTContext; // ASTContext creates these.
-
-public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArrayWithoutExpr;
- }
- static bool classof(const ConstantArrayWithoutExprType *) { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- assert(0 && "Cannot unique ConstantArrayWithoutExprTypes.");
- }
-};
-
/// IncompleteArrayType - This class represents C arrays with an unspecified
/// size. For example 'int A[]' has an IncompleteArrayType where the element
/// type is 'int' and the size is unspecified.
TYPE(MemberPointer, Type)
ABSTRACT_TYPE(Array, Type)
TYPE(ConstantArray, ArrayType)
-NON_CANONICAL_TYPE(ConstantArrayWithExpr, ConstantArrayType)
-NON_CANONICAL_TYPE(ConstantArrayWithoutExpr, ConstantArrayType)
TYPE(IncompleteArray, ArrayType)
TYPE(VariableArray, ArrayType)
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
TYPE_OBJC_PROTOCOL_LIST = 23,
/// \brief a DecltypeType record.
TYPE_DECLTYPE = 24,
- /// \brief A ConstantArrayWithExprType record.
- TYPE_CONSTANT_ARRAY_WITH_EXPR = 25,
- /// \brief A ConstantArrayWithoutExprType record.
- TYPE_CONSTANT_ARRAY_WITHOUT_EXPR = 26,
/// \brief An ElaboratedType record.
- TYPE_ELABORATED = 27
+ TYPE_ELABORATED = 25
};
/// \brief The type IDs for special types constructed by semantic
Align = getTypeAlign(cast<ArrayType>(T)->getElementType());
break;
- case Type::ConstantArrayWithExpr:
- case Type::ConstantArrayWithoutExpr:
case Type::ConstantArray: {
const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
return QualType(New, 0);
}
-/// getConstantArrayWithExprType - Return a reference to the type for
-/// an array of the specified element type.
-QualType
-ASTContext::getConstantArrayWithExprType(QualType EltTy,
- const llvm::APInt &ArySizeIn,
- Expr *ArySizeExpr,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals,
- SourceRange Brackets) {
- // Convert the array size into a canonical width matching the pointer
- // size for the target.
- llvm::APInt ArySize(ArySizeIn);
- ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
-
- // Compute the canonical ConstantArrayType.
- QualType Canonical = getConstantArrayType(getCanonicalType(EltTy),
- ArySize, ASM, EltTypeQuals);
- // Since we don't unique expressions, it isn't possible to unique VLA's
- // that have an expression provided for their size.
- ConstantArrayWithExprType *New = new(*this, TypeAlignment)
- ConstantArrayWithExprType(EltTy, Canonical, ArySize, ArySizeExpr,
- ASM, EltTypeQuals, Brackets);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
-/// getConstantArrayWithoutExprType - Return a reference to the type for
-/// an array of the specified element type.
-QualType
-ASTContext::getConstantArrayWithoutExprType(QualType EltTy,
- const llvm::APInt &ArySizeIn,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals) {
- // Convert the array size into a canonical width matching the pointer
- // size for the target.
- llvm::APInt ArySize(ArySizeIn);
- ArySize.zextOrTrunc(Target.getPointerWidth(EltTy.getAddressSpace()));
-
- // Compute the canonical ConstantArrayType.
- QualType Canonical = getConstantArrayType(getCanonicalType(EltTy),
- ArySize, ASM, EltTypeQuals);
- ConstantArrayWithoutExprType *New = new(*this, TypeAlignment)
- ConstantArrayWithoutExprType(EltTy, Canonical, ArySize, ASM, EltTypeQuals);
- Types.push_back(New);
- return QualType(New, 0);
-}
-
/// getVariableArrayType - Returns a non-unique reference to the type for a
/// variable array of the specified element type.
QualType ASTContext::getVariableArrayType(QualType EltTy,
C.Deallocate(this);
}
-void ConstantArrayWithExprType::Destroy(ASTContext& C) {
- // FIXME: destruction of SizeExpr commented out due to resource contention.
- // SizeExpr->Destroy(C);
- // See FIXME in SemaDecl.cpp:1536: if we were able to either steal
- // or clone the SizeExpr there, then here we could freely delete it.
- // Since we do not know how to steal or clone, we keep a pointer to
- // a shared resource, but we cannot free it.
- // (There probably is a trivial solution ... for people knowing clang!).
- this->~ConstantArrayWithExprType();
- C.Deallocate(this);
-}
-
void VariableArrayType::Destroy(ASTContext& C) {
if (SizeExpr)
SizeExpr->Destroy(C);
case Pointer:
case VariableArray:
case ConstantArray:
- case ConstantArrayWithExpr:
- case ConstantArrayWithoutExpr:
case IncompleteArray:
case FunctionProto:
case FunctionNoProto:
getElementType().getAsStringInternal(S, Policy);
}
-void ConstantArrayWithExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- if (Policy.ConstantArraySizeAsWritten) {
- std::string SStr;
- llvm::raw_string_ostream s(SStr);
- getSizeExpr()->printPretty(s, 0, Policy);
- S += '[';
- S += s.str();
- S += ']';
- getElementType().getAsStringInternal(S, Policy);
- }
- else
- ConstantArrayType::getAsStringInternal(S, Policy);
-}
-
-void ConstantArrayWithoutExprType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
- if (Policy.ConstantArraySizeAsWritten) {
- S += "[]";
- getElementType().getAsStringInternal(S, Policy);
- }
- else
- ConstantArrayType::getAsStringInternal(S, Policy);
-}
-
void IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
S += "[]";
Unit);
case Type::ConstantArray:
- case Type::ConstantArrayWithExpr:
- case Type::ConstantArrayWithoutExpr:
case Type::VariableArray:
case Type::IncompleteArray:
return CreateType(cast<ArrayType>(Ty), Unit);
ASM, IndexTypeQuals);
}
- case pch::TYPE_CONSTANT_ARRAY_WITH_EXPR: {
- QualType ElementType = GetType(Record[0]);
- ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
- unsigned IndexTypeQuals = Record[2];
- SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]);
- SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]);
- unsigned Idx = 5;
- llvm::APInt Size = ReadAPInt(Record, Idx);
- return Context->getConstantArrayWithExprType(ElementType,
- Size, ReadTypeExpr(),
- ASM, IndexTypeQuals,
- SourceRange(LBLoc, RBLoc));
- }
-
- case pch::TYPE_CONSTANT_ARRAY_WITHOUT_EXPR: {
- QualType ElementType = GetType(Record[0]);
- ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
- unsigned IndexTypeQuals = Record[2];
- unsigned Idx = 3;
- llvm::APInt Size = ReadAPInt(Record, Idx);
- return Context->getConstantArrayWithoutExprType(ElementType, Size,
- ASM, IndexTypeQuals);
- }
-
case pch::TYPE_INCOMPLETE_ARRAY: {
QualType ElementType = GetType(Record[0]);
ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1];
Code = pch::TYPE_CONSTANT_ARRAY;
}
-void PCHTypeWriter
-::VisitConstantArrayWithExprType(const ConstantArrayWithExprType *T) {
- VisitArrayType(T);
- Writer.AddSourceLocation(T->getLBracketLoc(), Record);
- Writer.AddSourceLocation(T->getRBracketLoc(), Record);
- Writer.AddAPInt(T->getSize(), Record);
- Writer.AddStmt(T->getSizeExpr());
- Code = pch::TYPE_CONSTANT_ARRAY_WITH_EXPR;
-}
-
-void PCHTypeWriter
-::VisitConstantArrayWithoutExprType(const ConstantArrayWithoutExprType *T) {
- VisitArrayType(T);
- Writer.AddAPInt(T->getSize(), Record);
- Code = pch::TYPE_CONSTANT_ARRAY_WITHOUT_EXPR;
-}
-
void PCHTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
VisitArrayType(T);
Code = pch::TYPE_INCOMPLETE_ARRAY;
// Set the length of the array to 1 (C99 6.9.2p5).
Diag(VD->getLocation(), diag::warn_tentative_incomplete_array);
llvm::APInt One(Context.getTypeSize(Context.getSizeType()), true);
- QualType T
- = Context.getConstantArrayWithoutExprType(ArrayT->getElementType(),
- One, ArrayType::Normal, 0);
+ QualType T = Context.getConstantArrayType(ArrayT->getElementType(),
+ One, ArrayType::Normal, 0);
VD->setType(T);
} else if (RequireCompleteType(VD->getLocation(), VD->getType(),
diag::err_tentative_def_incomplete_type))
llvm::APSInt &Res = EvalResult.Val.getInt();
if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) {
- Expr* ArySizeExpr = VLATy->getSizeExpr();
- // FIXME: here we could "steal" (how?) ArySizeExpr from the VLA,
- // so as to transfer ownership to the ConstantArrayWithExpr.
- // Alternatively, we could "clone" it (how?).
- // Since we don't know how to do things above, we just use the
- // very same Expr*.
- return Context.getConstantArrayWithExprType(VLATy->getElementType(),
- Res, ArySizeExpr,
- ArrayType::Normal, 0,
- VLATy->getBracketsRange());
+ // TODO: preserve the size expression in declarator info
+ return Context.getConstantArrayType(VLATy->getElementType(),
+ Res, ArrayType::Normal, 0);
}
SizeIsNegative = true;
llvm::APSInt ConstVal(32);
ConstVal = StrLength;
// Return a new array type (C99 6.7.8p22).
- DeclT = S.Context.getConstantArrayWithoutExprType(IAT->getElementType(),
- ConstVal,
- ArrayType::Normal, 0);
+ DeclT = S.Context.getConstantArrayType(IAT->getElementType(),
+ ConstVal,
+ ArrayType::Normal, 0);
return;
}
<< ArraySize->getSourceRange();
}
}
- T = Context.getConstantArrayWithExprType(T, ConstVal, ArraySize,
- ASM, Quals, Brackets);
+ T = Context.getConstantArrayType(T, ConstVal, ASM, Quals);
}
// If this is not C99, extwarn about VLA's and C99 array size modifiers.
if (!getLangOptions().C99) {
const llvm::APInt &Size,
unsigned IndexTypeQuals);
- /// \brief Build a new constant array type given the element type, size
- /// modifier, (known) size of the array, size expression, and index type
- /// qualifiers.
- ///
- /// By default, performs semantic analysis when building the array type.
- /// Subclasses may override this routine to provide different behavior.
- QualType RebuildConstantArrayWithExprType(QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- Expr *SizeExpr,
- unsigned IndexTypeQuals,
- SourceRange BracketsRange);
-
- /// \brief Build a new constant array type given the element type, size
- /// modifier, (known) size of the array, and index type qualifiers.
- ///
- /// By default, performs semantic analysis when building the array type.
- /// Subclasses may override this routine to provide different behavior.
- QualType RebuildConstantArrayWithoutExprType(QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- unsigned IndexTypeQuals);
-
/// \brief Build a new incomplete array type given the element type, size
/// modifier, and index type qualifiers.
///
T->getIndexTypeCVRQualifiers());
}
-template<typename Derived>
-QualType
-TreeTransform<Derived>::TransformConstantArrayWithExprType(
- const ConstantArrayWithExprType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
- if (ElementType.isNull())
- return QualType();
-
- // Array bounds are not potentially evaluated contexts
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
-
- Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
- if (Size.isInvalid())
- return QualType();
-
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType() &&
- Size.get() == T->getSizeExpr())
- return QualType(T, 0);
-
- return getDerived().RebuildConstantArrayWithExprType(ElementType,
- T->getSizeModifier(),
- T->getSize(),
- Size.takeAs<Expr>(),
- T->getIndexTypeCVRQualifiers(),
- T->getBracketsRange());
-}
-
-template<typename Derived>
-QualType
-TreeTransform<Derived>::TransformConstantArrayWithoutExprType(
- const ConstantArrayWithoutExprType *T) {
- QualType ElementType = getDerived().TransformType(T->getElementType());
- if (ElementType.isNull())
- return QualType();
-
- if (!getDerived().AlwaysRebuild() &&
- ElementType == T->getElementType())
- return QualType(T, 0);
-
- return getDerived().RebuildConstantArrayWithoutExprType(ElementType,
- T->getSizeModifier(),
- T->getSize(),
- T->getIndexTypeCVRQualifiers());
-}
-
template<typename Derived>
QualType TreeTransform<Derived>::TransformIncompleteArrayType(
const IncompleteArrayType *T) {
IndexTypeQuals, SourceRange());
}
-template<typename Derived>
-QualType
-TreeTransform<Derived>::RebuildConstantArrayWithExprType(QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- Expr *SizeExpr,
- unsigned IndexTypeQuals,
- SourceRange BracketsRange) {
- return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
- IndexTypeQuals, BracketsRange);
-}
-
-template<typename Derived>
-QualType
-TreeTransform<Derived>::RebuildConstantArrayWithoutExprType(
- QualType ElementType,
- ArrayType::ArraySizeModifier SizeMod,
- const llvm::APInt &Size,
- unsigned IndexTypeQuals) {
- return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
- IndexTypeQuals, SourceRange());
-}
-
template<typename Derived>
QualType
TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,