Teach ASTContext to delete all created types in its dtor.

Teach getPointerType to (stupidly) memoize all created pointers.
Give types an enum so we can implement classof.

llvm-svn: 39174
This commit is contained in:
Chris Lattner 2006-11-12 00:53:46 +00:00
parent 970e54e3ac
commit d5973ebbe2
4 changed files with 72 additions and 27 deletions

View File

@ -22,52 +22,72 @@ ASTContext::ASTContext(Preprocessor &pp)
InitBuiltinTypes();
}
ASTContext::~ASTContext() {
// Deallocate all the types.
while (!Types.empty()) {
delete Types.back();
Types.pop_back();
}
}
void ASTContext::InitBuiltinType(TypeRef &R, const char *Name) {
Types.push_back((R = new BuiltinType(Name)).getTypePtr());
}
void ASTContext::InitBuiltinTypes() {
assert(VoidTy.isNull() && "Context reinitialized?");
// C99 6.2.5p19.
Types.push_back(VoidTy = new BuiltinType("void"));
InitBuiltinType(VoidTy, "void");
// C99 6.2.5p2.
Types.push_back(BoolTy = new BuiltinType("_Bool"));
InitBuiltinType(BoolTy, "_Bool");
// C99 6.2.5p3.
Types.push_back(CharTy = new BuiltinType("char"));
InitBuiltinType(CharTy, "char");
// C99 6.2.5p4.
Types.push_back(SignedCharTy = new BuiltinType("signed char"));
Types.push_back(ShortTy = new BuiltinType("short"));
Types.push_back(IntTy = new BuiltinType("int"));
Types.push_back(LongTy = new BuiltinType("long"));
Types.push_back(LongLongTy = new BuiltinType("long long"));
InitBuiltinType(SignedCharTy, "signed char");
InitBuiltinType(ShortTy, "short");
InitBuiltinType(IntTy, "int");
InitBuiltinType(LongTy, "long");
InitBuiltinType(LongLongTy, "long long");
// C99 6.2.5p6.
Types.push_back(UnsignedCharTy = new BuiltinType("unsigned char"));
Types.push_back(UnsignedShortTy = new BuiltinType("unsigned short"));
Types.push_back(UnsignedIntTy = new BuiltinType("unsigned int"));
Types.push_back(UnsignedLongTy = new BuiltinType("unsigned long"));
Types.push_back(UnsignedLongLongTy = new BuiltinType("unsigned long long"));
InitBuiltinType(UnsignedCharTy, "unsigned char");
InitBuiltinType(UnsignedShortTy, "unsigned short");
InitBuiltinType(UnsignedIntTy, "unsigned int");
InitBuiltinType(UnsignedLongTy, "unsigned long");
InitBuiltinType(UnsignedLongLongTy, "unsigned long long");
// C99 6.2.5p10.
Types.push_back(FloatTy = new BuiltinType("float"));
Types.push_back(DoubleTy = new BuiltinType("double"));
Types.push_back(LongDoubleTy = new BuiltinType("long double"));
InitBuiltinType(FloatTy, "float");
InitBuiltinType(DoubleTy, "double");
InitBuiltinType(LongDoubleTy, "long double");
// C99 6.2.5p11.
Types.push_back(FloatComplexTy = new BuiltinType("float _Complex"));
Types.push_back(DoubleComplexTy = new BuiltinType("double _Complex"));
Types.push_back(LongDoubleComplexTy= new BuiltinType("long double _Complex"));
InitBuiltinType(FloatComplexTy, "float _Complex");
InitBuiltinType(DoubleComplexTy, "double _Complex");
InitBuiltinType(LongDoubleComplexTy, "long double _Complex");
}
/// getPointerType - Return the uniqued reference to the type for a pointer to
/// the specified type.
TypeRef ASTContext::getPointerType(const TypeRef &T) {
// FIXME: memoize these.
// FIXME: This is obviously braindead!
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
for (unsigned i = 0, e = Types.size(); i != e; ++i)
if (Types[i]->getTypeClass() == Type::Pointer)
if (((PointerType*)Types[i])->getPointee() == T)
return Types[i];
Type *Canonical = 0;
if (!T->isCanonical())
Canonical = getPointerType(T.getCanonicalType()).getTypePtr();
return new PointerType(T, Canonical);
Types.push_back(new PointerType(T, Canonical));
return Types.back();
}

View File

@ -23,7 +23,7 @@ Type::~Type() {}
//===----------------------------------------------------------------------===//
PointerType::PointerType(TypeRef Pointee, Type *Canonical)
: Type(Canonical), PointeeType(Pointee) {
: Type(Pointer, Canonical), PointeeType(Pointee) {
}

View File

@ -26,12 +26,11 @@ namespace clang {
/// decls) that can be referred to throughout the semantic analysis of a file.
class ASTContext {
// FIXME: This is a stupid data structure.
std::vector<TypeRef> Types;
std::vector<Type*> Types;
public:
Preprocessor &PP;
TargetInfo &Target;
// Builtin Types.
TypeRef VoidTy;
TypeRef BoolTy;
@ -43,6 +42,7 @@ public:
TypeRef FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
ASTContext(Preprocessor &pp);
~ASTContext();
/// getPointerType - Return the uniqued reference to the type for a pointer to
@ -51,6 +51,7 @@ public:
private:
void InitBuiltinTypes();
void InitBuiltinType(TypeRef &R, const char *Name);
};
} // end namespace clang

View File

@ -91,6 +91,15 @@ public:
return TypeRef(getTypePtr());
}
/// operator==/!= - Indicate whether the specified types and qualifiers are
/// identical.
bool operator==(const TypeRef &RHS) const {
return ThePtr == RHS.ThePtr;
}
bool operator!=(const TypeRef &RHS) const {
return ThePtr != RHS.ThePtr;
}
/// getCanonicalType - Return the canonical version of this type, with the
/// appropriate type qualifiers on it.
inline TypeRef getCanonicalType() const;
@ -126,11 +135,24 @@ public:
/// Types, once created, are immutable.
///
class Type {
public:
enum TypeClass {
Builtin,
Pointer,
Typedef
// ...
};
private:
TypeClass TC : 4;
Type *CanonicalType;
public:
Type(Type *Canonical) : CanonicalType(Canonical ? Canonical : this) {}
Type(TypeClass tc, Type *Canonical)
: TC(tc), CanonicalType(Canonical ? Canonical : this) {}
virtual ~Type();
TypeClass getTypeClass() const { return TC; }
bool isCanonical() const { return CanonicalType == this; }
Type *getCanonicalType() const { return CanonicalType; }
@ -142,7 +164,7 @@ public:
class BuiltinType : public Type {
const char *Name;
public:
BuiltinType(const char *name) : Type(0), Name(name) {}
BuiltinType(const char *name) : Type(Builtin, 0), Name(name) {}
virtual void print(std::ostream &OS) const;
};
@ -152,6 +174,8 @@ class PointerType : public Type {
PointerType(TypeRef Pointee, Type *CanonicalPtr = 0);
friend class ASTContext; // ASTContext creates these.
public:
TypeRef getPointee() const { return PointeeType; }
virtual void print(std::ostream &OS) const;
};