forked from OSchip/llvm-project
Create a new TypeNameType class, which represents typedefs as types. This
allows us to handle stuff like: typedef int G; .. X = sizeof(G); llvm-svn: 39189
This commit is contained in:
parent
2ebe4bb64d
commit
d0342e5989
|
@ -12,7 +12,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
using namespace llvm;
|
||||
using namespace clang;
|
||||
|
@ -119,3 +119,20 @@ TypeRef ASTContext::getArrayType(TypeRef EltTy,ArrayType::ArraySizeModifier ASM,
|
|||
}
|
||||
|
||||
|
||||
/// getTypeDeclType - Return the unique reference to the type for the
|
||||
/// specified typename decl.
|
||||
TypeRef ASTContext::getTypeDeclType(TypeDecl *Decl) {
|
||||
// FIXME: This is obviously braindead!
|
||||
// Unique TypeDecl, to guarantee there is only one TypeDeclType.
|
||||
for (unsigned i = 0, e = Types.size(); i != e; ++i)
|
||||
if (TypeNameType *Ty = dyn_cast<TypeNameType>(Types[i]))
|
||||
if (Ty->getDecl() == Decl)
|
||||
return Types[i];
|
||||
|
||||
// FIXME: does this lose qualifiers from the typedef??
|
||||
|
||||
Type *Canonical = Decl->getType().getTypePtr();
|
||||
Types.push_back(new TypeNameType(Decl, Canonical));
|
||||
return Types.back();
|
||||
}
|
||||
|
||||
|
|
|
@ -73,10 +73,18 @@ static TypeRef ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) {
|
|||
case DeclSpec::TST_decimal64: // _Decimal64
|
||||
case DeclSpec::TST_decimal128: // _Decimal128
|
||||
assert(0 && "FIXME: GNU decimal extensions not supported yet!");
|
||||
//DeclSpec::TST_enum:
|
||||
//DeclSpec::TST_union:
|
||||
//DeclSpec::TST_struct:
|
||||
//DeclSpec::TST_typedef:
|
||||
//case DeclSpec::TST_enum:
|
||||
//case DeclSpec::TST_union:
|
||||
//case DeclSpec::TST_struct:
|
||||
case DeclSpec::TST_typedef: {
|
||||
Decl *D = (Decl *)DS.TypenameRep;
|
||||
assert(D && "Didn't get a decl for a typedef?");
|
||||
// FIXME: apply type quals!
|
||||
assert(DS.TypeSpecWidth == 0 && DS.TypeSpecComplex == 0 &&
|
||||
DS.TypeSpecSign == 0 && DS.TypeQualifiers == 0 &&
|
||||
"Can't handle qualifiers on typedef names yet!");
|
||||
return Ctx.getTypeDeclType(cast<TypedefDecl>(D));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Lex/IdentifierTable.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include <iostream>
|
||||
using namespace llvm;
|
||||
using namespace clang;
|
||||
|
@ -94,3 +96,7 @@ void ArrayType::getAsString(std::string &S) const {
|
|||
|
||||
ElementType.getAsString(S);
|
||||
}
|
||||
|
||||
void TypeNameType::getAsString(std::string &InnerString) const {
|
||||
InnerString += getDecl()->getIdentifier()->getName();
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ void Parser::Initialize() {
|
|||
DS.StorageClassSpec = DeclSpec::SCS_typedef;
|
||||
|
||||
// TODO: add a 'TST_builtin' type?
|
||||
DS.TypeSpecType = DeclSpec::TST_typedef;
|
||||
DS.TypeSpecType = DeclSpec::TST_int;
|
||||
|
||||
Declarator D(DS, Declarator::FileContext);
|
||||
D.SetIdentifier(PP.getIdentifierInfo("__builtin_va_list"),SourceLocation());
|
||||
|
|
|
@ -73,10 +73,18 @@ static TypeRef ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) {
|
|||
case DeclSpec::TST_decimal64: // _Decimal64
|
||||
case DeclSpec::TST_decimal128: // _Decimal128
|
||||
assert(0 && "FIXME: GNU decimal extensions not supported yet!");
|
||||
//DeclSpec::TST_enum:
|
||||
//DeclSpec::TST_union:
|
||||
//DeclSpec::TST_struct:
|
||||
//DeclSpec::TST_typedef:
|
||||
//case DeclSpec::TST_enum:
|
||||
//case DeclSpec::TST_union:
|
||||
//case DeclSpec::TST_struct:
|
||||
case DeclSpec::TST_typedef: {
|
||||
Decl *D = (Decl *)DS.TypenameRep;
|
||||
assert(D && "Didn't get a decl for a typedef?");
|
||||
// FIXME: apply type quals!
|
||||
assert(DS.TypeSpecWidth == 0 && DS.TypeSpecComplex == 0 &&
|
||||
DS.TypeSpecSign == 0 && DS.TypeQualifiers == 0 &&
|
||||
"Can't handle qualifiers on typedef names yet!");
|
||||
return Ctx.getTypeDeclType(cast<TypedefDecl>(D));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,10 @@ public:
|
|||
/// specified element type.
|
||||
TypeRef getArrayType(TypeRef EltTy, ArrayType::ArraySizeModifier ASM,
|
||||
unsigned EltTypeQuals, void *NumElts);
|
||||
|
||||
|
||||
/// getTypeDeclType - Return the unique reference to the type for the
|
||||
/// specified typename decl.
|
||||
TypeRef getTypeDeclType(TypeDecl *Decl);
|
||||
|
||||
private:
|
||||
void InitBuiltinTypes();
|
||||
|
|
|
@ -131,10 +131,10 @@ public:
|
|||
///
|
||||
/// There will be a Type object created for 'int'. Since int is canonical, its
|
||||
/// canonicaltype pointer points to itself. There is also a Type for 'foo' (a
|
||||
/// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next
|
||||
/// TypeNameType). Its CanonicalType pointer points to the 'int' Type. Next
|
||||
/// there is a PointerType that represents 'int*', which, like 'int', is
|
||||
/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical
|
||||
/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
|
||||
/// type is 'int*', and there is a TypeNameType for 'bar', whose canonical type
|
||||
/// is also 'int*'.
|
||||
///
|
||||
/// Non-canonical types are useful for emitting diagnostics, without losing
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
class Type {
|
||||
public:
|
||||
enum TypeClass {
|
||||
Builtin, Pointer, Array, Typedef
|
||||
Builtin, Pointer, Array, TypeName
|
||||
};
|
||||
private:
|
||||
Type *CanonicalType;
|
||||
|
@ -242,13 +242,18 @@ public:
|
|||
};
|
||||
|
||||
|
||||
class TypedefType : public Type {
|
||||
// Decl * here.
|
||||
class TypeNameType : public Type {
|
||||
TypeDecl *Decl;
|
||||
TypeNameType(TypeDecl *D, Type *can) : Type(TypeName, can), Decl(D) {}
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
public:
|
||||
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
|
||||
static bool classof(const TypedefType *) { return true; }
|
||||
TypeDecl *getDecl() const { return Decl; }
|
||||
|
||||
virtual void getAsString(std::string &InnerString) const;
|
||||
|
||||
static bool classof(const Type *T) { return T->getTypeClass() == TypeName; }
|
||||
static bool classof(const TypeNameType *) { return true; }
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue