diff options
| -rw-r--r-- | clang/AST/ASTContext.cpp | 50 | ||||
| -rw-r--r-- | clang/AST/Sema.h | 2 | ||||
| -rw-r--r-- | clang/AST/SemaType.cpp | 73 | ||||
| -rw-r--r-- | clang/AST/Type.cpp | 41 | ||||
| -rw-r--r-- | clang/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/Sema/SemaType.cpp | 73 | ||||
| -rw-r--r-- | clang/include/clang/AST/ASTContext.h | 8 | ||||
| -rw-r--r-- | clang/include/clang/AST/Type.h | 29 |
8 files changed, 153 insertions, 125 deletions
diff --git a/clang/AST/ASTContext.cpp b/clang/AST/ASTContext.cpp index 99e29cba4ba..357177bf084 100644 --- a/clang/AST/ASTContext.cpp +++ b/clang/AST/ASTContext.cpp @@ -12,12 +12,62 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" #include "clang/Lex/Preprocessor.h" using namespace llvm; using namespace clang; ASTContext::ASTContext(Preprocessor &pp) : PP(pp), Target(pp.getTargetInfo()) { + InitBuiltinTypes(); +} + +void ASTContext::InitBuiltinTypes() { + assert(VoidTy.isNull() && "Context reinitialized?"); + + // C99 6.2.5p19. + Types.push_back(VoidTy = new BuiltinType("void")); + + // C99 6.2.5p2. + Types.push_back(BoolTy = new BuiltinType("_Bool")); + // C99 6.2.5p3. + Types.push_back(CharTy = new BuiltinType("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")); + + // 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")); + + // 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")); + + // 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")); +} + +/// getPointerType - Return the uniqued reference to the type for a pointer to +/// the specified type. +TypeRef ASTContext::getPointerType(const TypeRef &T) { + // FIXME: memoize these. + + + + Type *Canonical = 0; + if (!T->isCanonical()) + Canonical = getPointerType(T.getCanonicalType()).getTypePtr(); + return new PointerType(T, Canonical); } diff --git a/clang/AST/Sema.h b/clang/AST/Sema.h index 83473519a19..09b461bccc2 100644 --- a/clang/AST/Sema.h +++ b/clang/AST/Sema.h @@ -38,7 +38,6 @@ class Sema : public Action { public: Sema(ASTContext &ctx, std::vector<Decl*> &prevInGroup) : Context(ctx), LastInGroupList(prevInGroup) { - InitializeBuiltinTypes(); } void Diag(SourceLocation Loc, unsigned DiagID, @@ -47,7 +46,6 @@ public: //===--------------------------------------------------------------------===// // Type Analysis / Processing: SemaType.cpp. // - void InitializeBuiltinTypes(); TypeRef GetTypeForDeclarator(Declarator &D, Scope *S); diff --git a/clang/AST/SemaType.cpp b/clang/AST/SemaType.cpp index b6447efc762..8a0bf4f09bd 100644 --- a/clang/AST/SemaType.cpp +++ b/clang/AST/SemaType.cpp @@ -17,61 +17,6 @@ using namespace llvm; using namespace clang; -namespace { - /// BuiltinType - This class is used for builtin types like 'int'. Builtin - /// types are always canonical and have a literal name field. - class BuiltinType : public Type { - const char *Name; - public: - BuiltinType(const char *name) : Name(name) {} - - virtual void dump() const; - }; -} - -// FIXME: REMOVE -#include <iostream> - -void BuiltinType::dump() const { - std::cerr << Name; -} - - -void Sema::InitializeBuiltinTypes() { - assert(Context.VoidTy.isNull() && "Context reinitialized?"); - - // C99 6.2.5p19. - Context.VoidTy = new BuiltinType("void"); - - // C99 6.2.5p2. - Context.BoolTy = new BuiltinType("_Bool"); - // C99 6.2.5p3. - Context.CharTy = new BuiltinType("char"); - // C99 6.2.5p4. - Context.SignedCharTy = new BuiltinType("signed char"); - Context.ShortTy = new BuiltinType("short"); - Context.IntTy = new BuiltinType("int"); - Context.LongTy = new BuiltinType("long"); - Context.LongLongTy = new BuiltinType("long long"); - - // C99 6.2.5p6. - Context.UnsignedCharTy = new BuiltinType("unsigned char"); - Context.UnsignedShortTy = new BuiltinType("unsigned short"); - Context.UnsignedIntTy = new BuiltinType("unsigned int"); - Context.UnsignedLongTy = new BuiltinType("unsigned long"); - Context.UnsignedLongLongTy = new BuiltinType("unsigned long long"); - - // C99 6.2.5p10. - Context.FloatTy = new BuiltinType("float"); - Context.DoubleTy = new BuiltinType("double"); - Context.LongDoubleTy = new BuiltinType("long double"); - - // C99 6.2.5p11. - Context.FloatComplexTy = new BuiltinType("float _Complex"); - Context.DoubleComplexTy = new BuiltinType("double _Complex"); - Context.LongDoubleComplexTy = new BuiltinType("long double _Complex"); -} - /// ConvertDeclSpecToType - Convert the specified declspec to the appropriate /// type object. This returns null on error. static TypeRef ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) { @@ -142,6 +87,22 @@ TypeRef Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // Apply const/volatile/restrict qualifiers to T. T = T.getQualifiedType(D.getDeclSpec().TypeQualifiers); + // Walk the DeclTypeInfo, building the recursive type as we go. + for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { + const DeclaratorTypeInfo &DeclType = D.getTypeObject(e-i-1); + switch (DeclType.Kind) { + default: assert(0 && "Unknown decltype!"); + case DeclaratorTypeInfo::Pointer: + T = Context.getPointerType(T); + + // Apply the pointer typequals to the pointer object. + T = T.getQualifiedType(DeclType.Ptr.TypeQuals); + break; + case DeclaratorTypeInfo::Array: + case DeclaratorTypeInfo::Function: + return TypeRef(); // FIXME: implement these! + } + } + return T; - return TypeRef(); } diff --git a/clang/AST/Type.cpp b/clang/AST/Type.cpp index 5633eaf141f..8a9c9975798 100644 --- a/clang/AST/Type.cpp +++ b/clang/AST/Type.cpp @@ -12,28 +12,53 @@ //===----------------------------------------------------------------------===// #include "clang/AST/Type.h" +#include <iostream> using namespace llvm; using namespace clang; Type::~Type() {} +//===----------------------------------------------------------------------===// +// Type Construction +//===----------------------------------------------------------------------===// + +PointerType::PointerType(TypeRef Pointee, Type *Canonical) + : Type(Canonical), PointeeType(Pointee) { +} + + + +//===----------------------------------------------------------------------===// +// Type Printing +//===----------------------------------------------------------------------===// -#include <iostream> // FIXME: REMOVE void TypeRef::dump() const { + print(std::cerr); + std::cerr << "\n"; +} + +void TypeRef::print(std::ostream &OS) const { if (isNull()) { - std::cerr << "NULL TYPE\n"; + OS << "NULL TYPE\n"; return; } - (*this)->dump(); + getTypePtr()->print(OS); // Print qualifiers as appropriate. if (isConstQualified()) - std::cerr << " const"; + OS << " const"; if (isVolatileQualified()) - std::cerr << " volatile"; + OS << " volatile"; if (isRestrictQualified()) - std::cerr << " restrict"; - - std::cerr << "\n"; + OS << " restrict"; +} + +void BuiltinType::print(std::ostream &OS) const { + OS << Name; +} + +void PointerType::print(std::ostream &OS) const { + PointeeType.print(OS); + OS << "*"; } diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index 83473519a19..09b461bccc2 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -38,7 +38,6 @@ class Sema : public Action { public: Sema(ASTContext &ctx, std::vector<Decl*> &prevInGroup) : Context(ctx), LastInGroupList(prevInGroup) { - InitializeBuiltinTypes(); } void Diag(SourceLocation Loc, unsigned DiagID, @@ -47,7 +46,6 @@ public: //===--------------------------------------------------------------------===// // Type Analysis / Processing: SemaType.cpp. // - void InitializeBuiltinTypes(); TypeRef GetTypeForDeclarator(Declarator &D, Scope *S); diff --git a/clang/Sema/SemaType.cpp b/clang/Sema/SemaType.cpp index b6447efc762..8a0bf4f09bd 100644 --- a/clang/Sema/SemaType.cpp +++ b/clang/Sema/SemaType.cpp @@ -17,61 +17,6 @@ using namespace llvm; using namespace clang; -namespace { - /// BuiltinType - This class is used for builtin types like 'int'. Builtin - /// types are always canonical and have a literal name field. - class BuiltinType : public Type { - const char *Name; - public: - BuiltinType(const char *name) : Name(name) {} - - virtual void dump() const; - }; -} - -// FIXME: REMOVE -#include <iostream> - -void BuiltinType::dump() const { - std::cerr << Name; -} - - -void Sema::InitializeBuiltinTypes() { - assert(Context.VoidTy.isNull() && "Context reinitialized?"); - - // C99 6.2.5p19. - Context.VoidTy = new BuiltinType("void"); - - // C99 6.2.5p2. - Context.BoolTy = new BuiltinType("_Bool"); - // C99 6.2.5p3. - Context.CharTy = new BuiltinType("char"); - // C99 6.2.5p4. - Context.SignedCharTy = new BuiltinType("signed char"); - Context.ShortTy = new BuiltinType("short"); - Context.IntTy = new BuiltinType("int"); - Context.LongTy = new BuiltinType("long"); - Context.LongLongTy = new BuiltinType("long long"); - - // C99 6.2.5p6. - Context.UnsignedCharTy = new BuiltinType("unsigned char"); - Context.UnsignedShortTy = new BuiltinType("unsigned short"); - Context.UnsignedIntTy = new BuiltinType("unsigned int"); - Context.UnsignedLongTy = new BuiltinType("unsigned long"); - Context.UnsignedLongLongTy = new BuiltinType("unsigned long long"); - - // C99 6.2.5p10. - Context.FloatTy = new BuiltinType("float"); - Context.DoubleTy = new BuiltinType("double"); - Context.LongDoubleTy = new BuiltinType("long double"); - - // C99 6.2.5p11. - Context.FloatComplexTy = new BuiltinType("float _Complex"); - Context.DoubleComplexTy = new BuiltinType("double _Complex"); - Context.LongDoubleComplexTy = new BuiltinType("long double _Complex"); -} - /// ConvertDeclSpecToType - Convert the specified declspec to the appropriate /// type object. This returns null on error. static TypeRef ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) { @@ -142,6 +87,22 @@ TypeRef Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // Apply const/volatile/restrict qualifiers to T. T = T.getQualifiedType(D.getDeclSpec().TypeQualifiers); + // Walk the DeclTypeInfo, building the recursive type as we go. + for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) { + const DeclaratorTypeInfo &DeclType = D.getTypeObject(e-i-1); + switch (DeclType.Kind) { + default: assert(0 && "Unknown decltype!"); + case DeclaratorTypeInfo::Pointer: + T = Context.getPointerType(T); + + // Apply the pointer typequals to the pointer object. + T = T.getQualifiedType(DeclType.Ptr.TypeQuals); + break; + case DeclaratorTypeInfo::Array: + case DeclaratorTypeInfo::Function: + return TypeRef(); // FIXME: implement these! + } + } + return T; - return TypeRef(); } diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index e12d49c7cea..ecbcf7343ee 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_ASTCONTEXT_H #include "clang/AST/Type.h" +#include <vector> namespace llvm { namespace clang { @@ -24,6 +25,8 @@ 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 { + // FIXME: This is a stupid data structure. + std::vector<TypeRef> Types; public: Preprocessor &PP; TargetInfo &Target; @@ -42,7 +45,12 @@ public: ASTContext(Preprocessor &pp); + /// getPointerType - Return the uniqued reference to the type for a pointer to + /// the specified type. + TypeRef getPointerType(const TypeRef &T); +private: + void InitBuiltinTypes(); }; } // end namespace clang diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index fa55f162ef4..297865c82dd 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -16,9 +16,11 @@ #include "llvm/Support/DataTypes.h" #include <cassert> +#include <iosfwd> namespace llvm { namespace clang { + class ASTContext; class TypeDecl; class Type; @@ -89,7 +91,11 @@ public: return TypeRef(getTypePtr()); } + /// getCanonicalType - Return the canonical version of this type, with the + /// appropriate type qualifiers on it. + inline TypeRef getCanonicalType() const; + void print(std::ostream &OS) const; void dump() const; }; @@ -122,18 +128,32 @@ public: class Type { Type *CanonicalType; public: + Type(Type *Canonical) : CanonicalType(Canonical ? Canonical : this) {} virtual ~Type(); bool isCanonical() const { return CanonicalType == this; } Type *getCanonicalType() const { return CanonicalType; } - virtual void dump() const = 0; + virtual void print(std::ostream &OS) const = 0; +}; + +/// BuiltinType - This class is used for builtin types like 'int'. Builtin +/// types are always canonical and have a literal name field. +class BuiltinType : public Type { + const char *Name; +public: + BuiltinType(const char *name) : Type(0), Name(name) {} + + virtual void print(std::ostream &OS) const; }; class PointerType : public Type { TypeRef PointeeType; + PointerType(TypeRef Pointee, Type *CanonicalPtr = 0); + friend class ASTContext; // ASTContext creates these. public: + virtual void print(std::ostream &OS) const; }; class TypedefType : public Type { @@ -151,6 +171,13 @@ public: // specify the same type, we want to print the default argument only if // specified in the source code. + +/// getCanonicalType - Return the canonical version of this type, with the +/// appropriate type qualifiers on it. +inline TypeRef TypeRef::getCanonicalType() const { + return TypeRef(getTypePtr()->getCanonicalType(), getQualifiers()); +} + } // end namespace clang } // end namespace llvm |

