summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/AST/ASTContext.cpp50
-rw-r--r--clang/AST/Sema.h2
-rw-r--r--clang/AST/SemaType.cpp73
-rw-r--r--clang/AST/Type.cpp41
-rw-r--r--clang/Sema/Sema.h2
-rw-r--r--clang/Sema/SemaType.cpp73
-rw-r--r--clang/include/clang/AST/ASTContext.h8
-rw-r--r--clang/include/clang/AST/Type.h29
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
OpenPOWER on IntegriCloud