VariableArrayTypes (VLAs) without a size expression are now uniqued

and inserted into a FoldingSet owned by ASTContext.

llvm-svn: 43482
This commit is contained in:
Ted Kremenek 2007-10-29 23:37:31 +00:00
parent 797f24cd7e
commit 843ebedde4
3 changed files with 58 additions and 7 deletions

View File

@ -451,11 +451,49 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
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);
if (NumElts) {
// Since we don't unique expressions, it isn't possible to unique VLA's
// that have an expression provided for their size.
ArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
ASM, EltTypeQuals);
// FIXME: Also add non-uniqued VLAs into a list of their own.
Types.push_back(New);
return QualType(New, 0);
}
else {
// No size is provided for the VLA. These we can unique.
llvm::FoldingSetNodeID ID;
VariableArrayType::Profile(ID, EltTy);
void *InsertPos = 0;
if (VariableArrayType *ATP =
IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(ATP, 0);
// If the element type isn't canonical, this won't be a canonical type
// either, so fill in the canonical type field.
QualType Canonical;
if (!EltTy->isCanonical()) {
Canonical = getVariableArrayType(EltTy.getCanonicalType(), NumElts,
ASM, EltTypeQuals);
// Get the new insert position for the node we care about.
VariableArrayType *NewIP =
IncompleteVariableArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(NewIP == 0 && "Shouldn't be in the map!");
}
VariableArrayType *New = new VariableArrayType(EltTy, QualType(), NumElts,
ASM, EltTypeQuals);
IncompleteVariableArrayTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
}
}
/// getVectorType - Return the unique reference to a vector type of

View File

@ -29,12 +29,13 @@ namespace clang {
/// ASTContext - This class holds long-lived AST nodes (such as types and
/// decls) that can be referred to throughout the semantic analysis of a file.
class ASTContext {
class ASTContext {
std::vector<Type*> Types;
llvm::FoldingSet<ComplexType> ComplexTypes;
llvm::FoldingSet<PointerType> PointerTypes;
llvm::FoldingSet<ReferenceType> ReferenceTypes;
llvm::FoldingSet<ConstantArrayType> ArrayTypes;
llvm::FoldingSet<VariableArrayType> IncompleteVariableArrayTypes;
llvm::FoldingSet<VectorType> VectorTypes;
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;

View File

@ -573,7 +573,7 @@ public:
};
// FIXME: VariableArrayType's aren't uniqued (since expressions aren't).
class VariableArrayType : public ArrayType {
class VariableArrayType : public ArrayType, public llvm::FoldingSetNode {
/// SizeExpr - An assignment expression. VLA's are only permitted within
/// a function block.
Expr *SizeExpr;
@ -593,6 +593,18 @@ public:
static bool classof(const VariableArrayType *) { return true; }
friend class StmtIteratorBase;
void Profile(llvm::FoldingSetNodeID &ID) {
assert (SizeExpr == NULL
&& "Can only unique VariableArrayTypes with no specified size.");
Profile(ID, getElementType());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ET) {
ID.AddPointer(ET.getAsOpaquePtr());
}
// FIXME: Who owns VariableArrayType's? What are the semantics
// for serialization.
};