Type类是所有类型的基类。谨记:每个类型都有一个标准类型(原始类型),标准类型就是去掉了typedef和引用部分的类型。
typedef int foo;
typedef foo * bar;
“int *” “foo *” “bar”
此处,会有一个类型对象int,因为int是标准类型,它的标准类型指针指向自身(标准类型的标准类型指针为自身)。同样的,对于类型foo(TypedefType)也会有一个类型对象,其标准类型指针指向int类型。接下来会有一个PointerType表示int *,和int一样,int*也是标准类型。同样的bar类型对象的标准类型是int *。
非标准类型对于给出诊断信息而言,是非常有用的,这样不会丢失typedef的类型信息。标准类型对于类型比较是非常有用的。
Type一经创建,便是不可修改的。
class Type{}
类中首先包含了一个enum TypeClass{}的类型。
enum TypeClass {
#define TYPE(Class, Base) Class,
#define LAST_TYPE(Class) TypeLast = Class,
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
TagFirst = Record, TagLast = Enum
};
文件TypeNodes.def是对AST 类型的数据库文件,其中每个类型节点都是通过其名字和基类枚举的。如Builtin或Enum,和Type或TagType。下列宏定义:
TYPE(Class, Base) 一个可以出现在AST中任何位置的类型,可能是dependent, canonical, non-canonical。
ABSTRACT_TYPE(Class, Base)一个抽象的类型,没有实例
NON_CANONICAL_TYPE(Class, Base)可以出现在AST中任何位置,但是不是canonical类型,只需要处理canonical类型的client可以忽略这些类型。
DEPENDENT_TYPE(Class, Base)只能出现在C++ template中的类型。
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)除非这个类型是dependent,否则是non-canonical。默认情况下为TYPE.
LEAF_TYPE(Class, Base)此类型没有内嵌类型,一般不使用
TypeNodes.def中定义的类型有:
TYPE(Builtin, Type)
TYPE(Complex, Type)
TYPE(Pointer, Type)
TYPE(BlockPointer, Type)
ABSTRACT_TYPE(Reference, Type)
TYPE(LValueReference, ReferenceType)
TYPE(RValueReference, ReferenceType)
TYPE(MemberPointer, Type)
ABSTRACT_TYPE(Array, Type)
TYPE(ConstantArray, ArrayType)
TYPE(IncompleteArray, ArrayType)
TYPE(VariableArray, ArrayType)
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
DEPENDENT_TYPE(DependentSizedExtVector, Type)
TYPE(Vector, Type)
TYPE(ExtVector, VectorType)
ABSTRACT_TYPE(Function, Type)
TYPE(FunctionProto, FunctionType)
TYPE(FunctionNoProto, FunctionType)
DEPENDENT_TYPE(UnresolvedUsing, Type)
NON_CANONICAL_TYPE(Typedef, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
ABSTRACT_TYPE(Tag, Type)
TYPE(Record, TagType)
TYPE(Enum, TagType)
NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
DEPENDENT_TYPE(DependentTemplateSpecialization, Type)
TYPE(ObjCObject, Type)
TYPE(ObjCInterface, ObjCObjectType)
TYPE(ObjCObjectPointer, Type)
在Type的定义中,其实只是将TYPE中的Class作为枚举使用。
Type中的变量:
QualType CanonicalType
union {
TypeBitfields TypeBits;
ArrayTypeBitfields ArrayTypeBits;
BuiltinTypeBitfields BuiltinTypeBits;
FunctionTypeBitfields FunctionTypeBits;
ObjCObjectTypeBitfields ObjCObjectTypeBits;
ReferenceTypeBitfields ReferenceTypeBits;
TypeWithKeywordBitfields TypeWithKeywordBits;
VectorTypeBitfields VectorTypeBits;
};
上述union中各个类型均为嵌入类
class TypeBitfields{}用于Type类的bit标记,其中包括:
unsigned TC : 8; //TypeClasses bitfield,说明该子类是哪一个,和前面的TypeClass枚举值相同
unsigned Dependent : 1;//该类型是不是一个依赖类型(C++ template)。
unsigned VariablyModified:1;//该类型是不是一个值可以修改的类型(C99 6.7.5)
mutable unsigned CacheValidAndVisibility : 2;//如果cache是有效的,那么为非0,此时这个值为LangOptions::VisibilityMode + 1;
mutable unsigned CachedLinkage : 2;//类型的链接类型。
mutable unsigned CachedLocalOrUnnamed : 1;
mutable unsigned FromAST: 1;//该类型是不是从AST文件中来的。
接下来定义了枚举类型NumTypeBits = 16,以说明前面的类的长度为16bits。
ArrayTypeBitfields{}允许子类把bitfields包入类型中,其中包括:
unsigned : NumTypeBits;//这正是前面的TypeBitfields
unsigned IndexTypeQuals : 3;//声明中类似int x[static restrict 4]的CVR限定符,只能用于函数的参数。
unsigned SizeModifier : 3;存储类型说明符,例如int x[static restrict t].只能用于函数参数,实际上,为ArrayType::ArraySizeModifier。
BuiltinTypeBitfields{},其中包括:
unsigned : NumTypeBits;
unsigned Kind : 8; //内建类型的种类,BuiltinType::Kind。
FunctionTypeBitfields{}其中包括:
unsigned : NumTypeBits;
unsigned ExtInfo : 8;//影响函数调用的额外信息,例如regparam和调用约定。
unsigned SubclassInfo : 1;//用于子类。
unsigned TypeQuals : 3;//只能用于FunctionProtoType,放在这里和其他一起打包,类型限定符是FunctionProtoType的一部分,见C++ 8.3.5p4;
ObjCObjectTypeBitfields{}只是OBJECTIVE-C的,无视~
ReferenceTypeBitfields{},其中包括:
unsigned : NumTypeBits;
unsigned SpelledAsLValue : 1; // 如果类型原本就被拼写为左值,那么为true,对于右值,永远为false,见C++ 0x,例如
//typedef int & ref; 只是左值,spelled lvalue
//typedef int && rvref 这是右值
//ref & a;
unsigned InnerRef : 1;//如果内置类型为引用,那么为true;只发生在non-canonical中。
TypeWithKeyWordsBitfields{}包括:
unsigned : NumTypeBits;
unsigned Keyword : 8; //ElaboratedTypeKeyword。
VectorTypeBitfields{}包括:
unsigned : NumTypeBits;
unsigned AltiVecSpec : 2;//AltiVecSpec向量信息,
unsigned NumElements : 30-NumTypeBits;//向量中元素数量
构造函数:
Type(TypeClass tc, QualType Canonical, bool Dependent, bool VariableModified)
Type类提供了所有类型的is判断函数;