From d5973ebbe2d3919151c6bfc32c66922d7d056444 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 12 Nov 2006 00:53:46 +0000 Subject: [PATCH] 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 --- clang/AST/ASTContext.cpp | 64 ++++++++++++++++++---------- clang/AST/Type.cpp | 2 +- clang/include/clang/AST/ASTContext.h | 5 ++- clang/include/clang/AST/Type.h | 28 +++++++++++- 4 files changed, 72 insertions(+), 27 deletions(-) diff --git a/clang/AST/ASTContext.cpp b/clang/AST/ASTContext.cpp index 357177bf084b..0e56dfbe13d2 100644 --- a/clang/AST/ASTContext.cpp +++ b/clang/AST/ASTContext.cpp @@ -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(); } diff --git a/clang/AST/Type.cpp b/clang/AST/Type.cpp index 8a9c9975798e..e3cc1ede826c 100644 --- a/clang/AST/Type.cpp +++ b/clang/AST/Type.cpp @@ -23,7 +23,7 @@ Type::~Type() {} //===----------------------------------------------------------------------===// PointerType::PointerType(TypeRef Pointee, Type *Canonical) - : Type(Canonical), PointeeType(Pointee) { + : Type(Pointer, Canonical), PointeeType(Pointee) { } diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ecbcf7343ee3..ab3d87397eec 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -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 Types; + std::vector 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 diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 297865c82dde..e775ce88047a 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -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; };