aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-26 23:50:07 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-26 23:50:07 +0000
commit72564e73277e29f6db3305d1f27ba408abb7ed88 (patch)
tree857ee84221eb8cb9b57d6b2e787347696c282f63
parent3a2503227c3db04a3619735127483263c1075ef7 (diff)
Create a new TypeNodes.def file that enumerates all of the types,
giving them rough classifications (normal types, never-canonical types, always-dependent types, abstract type representations) and making it far easier to make sure that we've hit all of the cases when decoding types. Switched some switch() statements on the type class over to using this mechanism, and filtering out those things we don't care about. For example, CodeGen should never see always-dependent or non-canonical types, while debug info generation should never see always-dependent types. More switch() statements on the type class need to be moved over to using this approach, so that we'll get warnings when we add a new type then fail to account for it somewhere in the compiler. As part of this, some types have been renamed: TypeOfExpr -> TypeOfExprType FunctionTypeProto -> FunctionProtoType FunctionTypeNoProto -> FunctionNoProtoType There shouldn't be any functionality change... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65591 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Driver/ASTConsumers.cpp4
-rw-r--r--Driver/RewriteBlocks.cpp28
-rw-r--r--Driver/RewriteObjC.cpp36
-rw-r--r--include/clang/AST/ASTContext.h10
-rw-r--r--include/clang/AST/DeclCXX.h2
-rw-r--r--include/clang/AST/Type.h111
-rw-r--r--include/clang/AST/TypeNodes.def83
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h2
-rw-r--r--lib/AST/ASTContext.cpp128
-rw-r--r--lib/AST/Builtins.cpp2
-rw-r--r--lib/AST/Decl.cpp4
-rw-r--r--lib/AST/DeclCXX.cpp8
-rw-r--r--lib/AST/StmtPrinter.cpp6
-rw-r--r--lib/AST/Type.cpp45
-rw-r--r--lib/AST/TypeSerialization.cpp48
-rw-r--r--lib/Analysis/CFRefCount.cpp2
-rw-r--r--lib/Analysis/GRExprEngine.cpp6
-rw-r--r--lib/CodeGen/CGBlocks.cpp10
-rw-r--r--lib/CodeGen/CGCall.cpp8
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp24
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--lib/CodeGen/CodeGenFunction.h2
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp23
-rw-r--r--lib/CodeGen/CodeGenTypes.h6
-rw-r--r--lib/CodeGen/Mangle.cpp4
-rw-r--r--lib/Sema/Sema.h4
-rw-r--r--lib/Sema/SemaChecking.cpp8
-rw-r--r--lib/Sema/SemaDecl.cpp16
-rw-r--r--lib/Sema/SemaDeclAttr.cpp10
-rw-r--r--lib/Sema/SemaDeclCXX.cpp18
-rw-r--r--lib/Sema/SemaExpr.cpp12
-rw-r--r--lib/Sema/SemaLookup.cpp4
-rw-r--r--lib/Sema/SemaOverload.cpp34
-rw-r--r--lib/Sema/SemaType.cpp10
34 files changed, 417 insertions, 303 deletions
diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp
index 6ad48c4357..cdfcb68b14 100644
--- a/Driver/ASTConsumers.cpp
+++ b/Driver/ASTConsumers.cpp
@@ -227,7 +227,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
std::string Proto = FD->getNameAsString();
const FunctionType *AFT = FD->getType()->getAsFunctionType();
- if (const FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) {
+ if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT)) {
Proto += "(";
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
if (i) Proto += ", ";
@@ -244,7 +244,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
}
Proto += ")";
} else {
- assert(isa<FunctionTypeNoProto>(AFT));
+ assert(isa<FunctionNoProtoType>(AFT));
Proto += "()";
}
diff --git a/Driver/RewriteBlocks.cpp b/Driver/RewriteBlocks.cpp
index 75aa3c863a..7eacc0a995 100644
--- a/Driver/RewriteBlocks.cpp
+++ b/Driver/RewriteBlocks.cpp
@@ -141,7 +141,7 @@ public:
void RewriteProtocolDecl(ObjCProtocolDecl *PDecl);
void RewriteMethodDecl(ObjCMethodDecl *MDecl);
- void RewriteFunctionTypeProto(QualType funcType, NamedDecl *D);
+ void RewriteFunctionProtoType(QualType funcType, NamedDecl *D);
void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
void RewriteCastExpr(CastExpr *CE);
@@ -370,12 +370,12 @@ std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i,
BlockDecl *BD = CE->getBlockDecl();
- if (isa<FunctionTypeNoProto>(AFT)) {
+ if (isa<FunctionNoProtoType>(AFT)) {
S += "()";
} else if (BD->param_empty()) {
S += "(" + StructRef + " *__cself)";
} else {
- const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
+ const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
assert(FT && "SynthesizeBlockFunc: No function proto");
S += '(';
// first add the implicit argument.
@@ -689,7 +689,7 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
assert(CPT && "RewriteBlockClass: Bad type");
const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType();
assert(FT && "RewriteBlockClass: Bad type");
- const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FT);
+ const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
// FTP will be null for closures that don't take arguments.
// Build a closure call - start with a paren expr to enforce precedence.
@@ -699,7 +699,7 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
BlockCall += "(" + Exp->getType().getAsString() + "(*)";
BlockCall += "(struct __block_impl *";
if (FTP) {
- for (FunctionTypeProto::arg_type_iterator I = FTP->arg_type_begin(),
+ for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
E = FTP->arg_type_end(); I && (I != E); ++I)
BlockCall += ", " + (*I).getAsString();
}
@@ -803,17 +803,17 @@ void RewriteBlocks::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
}
bool RewriteBlocks::PointerTypeTakesAnyBlockArguments(QualType QT) {
- const FunctionTypeProto *FTP;
+ const FunctionProtoType *FTP;
const PointerType *PT = QT->getAsPointerType();
if (PT) {
- FTP = PT->getPointeeType()->getAsFunctionTypeProto();
+ FTP = PT->getPointeeType()->getAsFunctionProtoType();
} else {
const BlockPointerType *BPT = QT->getAsBlockPointerType();
assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
- FTP = BPT->getPointeeType()->getAsFunctionTypeProto();
+ FTP = BPT->getPointeeType()->getAsFunctionProtoType();
}
if (FTP) {
- for (FunctionTypeProto::arg_type_iterator I = FTP->arg_type_begin(),
+ for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
E = FTP->arg_type_end(); I != E; ++I)
if (isBlockPointerType(*I))
return true;
@@ -1049,9 +1049,9 @@ Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) {
return S;
}
-void RewriteBlocks::RewriteFunctionTypeProto(QualType funcType, NamedDecl *D) {
- if (FunctionTypeProto *fproto = dyn_cast<FunctionTypeProto>(funcType)) {
- for (FunctionTypeProto::arg_type_iterator I = fproto->arg_type_begin(),
+void RewriteBlocks::RewriteFunctionProtoType(QualType funcType, NamedDecl *D) {
+ if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
+ for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
E = fproto->arg_type_end(); I && (I != E); ++I)
if (isBlockPointerType(*I)) {
// All the args are checked/rewritten. Don't call twice!
@@ -1064,7 +1064,7 @@ void RewriteBlocks::RewriteFunctionTypeProto(QualType funcType, NamedDecl *D) {
void RewriteBlocks::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
const PointerType *PT = funcType->getAsPointerType();
if (PT && PointerTypeTakesAnyBlockArguments(funcType))
- RewriteFunctionTypeProto(PT->getPointeeType(), ND);
+ RewriteFunctionProtoType(PT->getPointeeType(), ND);
}
/// HandleDeclInMainFile - This is called for each top-level decl defined in the
@@ -1074,7 +1074,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
// Since function prototypes don't have ParmDecl's, we check the function
// prototype. This enables us to rewrite function declarations and
// definitions using the same code.
- RewriteFunctionTypeProto(FD->getType(), FD);
+ RewriteFunctionProtoType(FD->getType(), FD);
if (Stmt *Body = FD->getBody()) {
CurFunctionDef = FD;
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp
index bd95a3922a..7293201166 100644
--- a/Driver/RewriteObjC.cpp
+++ b/Driver/RewriteObjC.cpp
@@ -311,7 +311,7 @@ namespace {
void SynthesizeMetaDataIntoBuffer(std::string &Result);
// Block rewriting.
- void RewriteBlocksInFunctionTypeProto(QualType funcType, NamedDecl *D);
+ void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
@@ -371,10 +371,10 @@ namespace {
};
}
-void RewriteObjC::RewriteBlocksInFunctionTypeProto(QualType funcType,
+void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
NamedDecl *D) {
- if (FunctionTypeProto *fproto = dyn_cast<FunctionTypeProto>(funcType)) {
- for (FunctionTypeProto::arg_type_iterator I = fproto->arg_type_begin(),
+ if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
+ for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
E = fproto->arg_type_end(); I && (I != E); ++I)
if (isTopLevelBlockPointerType(*I)) {
// All the args are checked/rewritten. Don't call twice!
@@ -387,7 +387,7 @@ void RewriteObjC::RewriteBlocksInFunctionTypeProto(QualType funcType,
void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
const PointerType *PT = funcType->getAsPointerType();
if (PT && PointerTypeTakesAnyBlockArguments(funcType))
- RewriteBlocksInFunctionTypeProto(PT->getPointeeType(), ND);
+ RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
}
static bool IsHeaderFile(const std::string &Filename) {
@@ -956,7 +956,7 @@ void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
ResultStr += ")"; // close the precedence "scope" for "*".
// Now, emit the argument types (if any).
- if (const FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(FPRetType)) {
+ if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
ResultStr += "(";
for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
if (i) ResultStr += ", ";
@@ -1855,7 +1855,7 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
SourceLocation Loc;
QualType Type;
- const FunctionTypeProto *proto = 0;
+ const FunctionProtoType *proto = 0;
if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
Loc = VD->getLocation();
Type = VD->getType();
@@ -1866,7 +1866,7 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
// information (id<p>, C<p>*). The protocol references need to be rewritten!
const FunctionType *funcType = FD->getType()->getAsFunctionType();
assert(funcType && "missing function type");
- proto = dyn_cast<FunctionTypeProto>(funcType);
+ proto = dyn_cast<FunctionProtoType>(funcType);
if (!proto)
return;
Type = proto->getResultType();
@@ -3482,14 +3482,14 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
BlockDecl *BD = CE->getBlockDecl();
- if (isa<FunctionTypeNoProto>(AFT)) {
+ if (isa<FunctionNoProtoType>(AFT)) {
// No user-supplied arguments. Still need to pass in a pointer to the
// block (to reference imported block decl refs).
S += "(" + StructRef + " *__cself)";
} else if (BD->param_empty()) {
S += "(" + StructRef + " *__cself)";
} else {
- const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
+ const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
assert(FT && "SynthesizeBlockFunc: No function proto");
S += '(';
// first add the implicit argument.
@@ -3806,7 +3806,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
assert(CPT && "RewriteBlockClass: Bad type");
const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType();
assert(FT && "RewriteBlockClass: Bad type");
- const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FT);
+ const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
// FTP will be null for closures that don't take arguments.
RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
@@ -3820,7 +3820,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
// Push the block argument type.
ArgTypes.push_back(PtrBlock);
if (FTP) {
- for (FunctionTypeProto::arg_type_iterator I = FTP->arg_type_begin(),
+ for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
E = FTP->arg_type_end(); I && (I != E); ++I) {
QualType t = *I;
// Make sure we convert "t (^)(...)" to "t (*)(...)".
@@ -3951,17 +3951,17 @@ void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
}
bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
- const FunctionTypeProto *FTP;
+ const FunctionProtoType *FTP;
const PointerType *PT = QT->getAsPointerType();
if (PT) {
- FTP = PT->getPointeeType()->getAsFunctionTypeProto();
+ FTP = PT->getPointeeType()->getAsFunctionProtoType();
} else {
const BlockPointerType *BPT = QT->getAsBlockPointerType();
assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
- FTP = BPT->getPointeeType()->getAsFunctionTypeProto();
+ FTP = BPT->getPointeeType()->getAsFunctionProtoType();
}
if (FTP) {
- for (FunctionTypeProto::arg_type_iterator I = FTP->arg_type_begin(),
+ for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
E = FTP->arg_type_end(); I != E; ++I)
if (isTopLevelBlockPointerType(*I))
return true;
@@ -4061,7 +4061,7 @@ void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
IdentifierInfo *ID = &Context->Idents.get(name);
- QualType FType = Context->getFunctionTypeNoProto(Context->VoidPtrTy);
+ QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
return FunctionDecl::Create(*Context, TUDecl,SourceLocation(),
ID, FType, FunctionDecl::Extern, false,
false);
@@ -4424,7 +4424,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
// Since function prototypes don't have ParmDecl's, we check the function
// prototype. This enables us to rewrite function declarations and
// definitions using the same code.
- RewriteBlocksInFunctionTypeProto(FD->getType(), FD);
+ RewriteBlocksInFunctionProtoType(FD->getType(), FD);
if (Stmt *Body = FD->getBody()) {
CurFunctionDef = FD;
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 74a999366b..a39095f4f8 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -66,8 +66,8 @@ class ASTContext {
std::vector<VariableArrayType*> VariableArrayTypes;
std::vector<DependentSizedArrayType*> DependentSizedArrayTypes;
llvm::FoldingSet<VectorType> VectorTypes;
- llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
- llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
+ llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
+ llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
llvm::FoldingSet<ClassTemplateSpecializationType>
ClassTemplateSpecializationTypes;
@@ -251,9 +251,9 @@ public:
/// type.
QualType getExtVectorType(QualType VectorType, unsigned NumElts);
- /// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
+ /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
///
- QualType getFunctionTypeNoProto(QualType ResultTy);
+ QualType getFunctionNoProtoType(QualType ResultTy);
/// getFunctionType - Return a normal function type with a typed argument
/// list. isVariadic indicates whether the argument list includes '...'.
@@ -293,7 +293,7 @@ public:
/// getTypeOfType - GCC extension.
- QualType getTypeOfExpr(Expr *e);
+ QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t);
/// getTagDeclType - Return the unique reference to the type for the
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index a9d6a7dbd5..875010bd2f 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -419,7 +419,7 @@ public:
QualType getThisType(ASTContext &C) const;
unsigned getTypeQualifiers() const {
- return getType()->getAsFunctionTypeProto()->getTypeQuals();
+ return getType()->getAsFunctionProtoType()->getTypeQuals();
}
// Implement isa/cast/dyncast/etc.
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 3ee513b17f..3ca695c0b8 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -45,32 +45,11 @@ namespace clang {
class Expr;
class Stmt;
class SourceLocation;
- class PointerType;
- class BlockPointerType;
- class ReferenceType;
- class MemberPointerType;
- class VectorType;
- class ArrayType;
- class ConstantArrayType;
- class VariableArrayType;
- class IncompleteArrayType;
- class DependentSizedArrayType;
- class RecordType;
- class EnumType;
- class ComplexType;
- class TagType;
- class TypedefType;
- class TemplateTypeParmType;
- class FunctionType;
- class FunctionTypeNoProto;
- class FunctionTypeProto;
- class ExtVectorType;
- class BuiltinType;
- class ObjCInterfaceType;
- class ObjCQualifiedIdType;
- class ObjCQualifiedInterfaceType;
class StmtIteratorBase;
- class ClassTemplateSpecializationType;
+
+ // Provide forward declarations for all of the *Type classes
+#define TYPE(Class, Base) class Class##Type;
+#include "clang/AST/TypeNodes.def"
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
/// their own: instead each reference to a type stores the qualifiers. This
@@ -244,10 +223,10 @@ namespace clang {
///
/// 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
-/// TypeNameType). Its CanonicalType pointer points to the 'int' Type. Next
+/// TypedefType). 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 TypeNameType for 'bar', whose canonical type
+/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
/// is also 'int*'.
///
/// Non-canonical types are useful for emitting diagnostics, without losing
@@ -261,17 +240,10 @@ namespace clang {
class Type {
public:
enum TypeClass {
- Builtin, Complex, Pointer, Reference, MemberPointer,
- ConstantArray, VariableArray, IncompleteArray, DependentSizedArray,
- Vector, ExtVector,
- FunctionNoProto, FunctionProto,
- TypeName, Tagged, ExtQual,
- TemplateTypeParm, ClassTemplateSpecialization,
- ObjCInterface, ObjCQualifiedInterface,
- ObjCQualifiedId, ObjCQualifiedClass,
- TypeOfExp, TypeOfTyp, // GNU typeof extension.
- BlockPointer, // C extension
- FixedWidthInt
+#define TYPE(Class, Base) Class,
+#define ABSTRACT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+ TagFirst = Record, TagLast = Enum
};
private:
@@ -401,8 +373,8 @@ public:
// the best type we can.
const BuiltinType *getAsBuiltinType() const;
const FunctionType *getAsFunctionType() const;
- const FunctionTypeNoProto *getAsFunctionTypeNoProto() const;
- const FunctionTypeProto *getAsFunctionTypeProto() const;
+ const FunctionNoProtoType *getAsFunctionNoProtoType() const;
+ const FunctionProtoType *getAsFunctionProtoType() const;
const PointerType *getAsPointerType() const;
const BlockPointerType *getAsBlockPointerType() const;
const ReferenceType *getAsReferenceType() const;
@@ -1096,16 +1068,16 @@ public:
};
/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
-/// class of FunctionTypeNoProto and FunctionTypeProto.
+/// class of FunctionNoProtoType and FunctionProtoType.
///
class FunctionType : public Type {
/// SubClassData - This field is owned by the subclass, put here to pack
/// tightly with the ivars in Type.
bool SubClassData : 1;
- /// TypeQuals - Used only by FunctionTypeProto, put here to pack with the
+ /// TypeQuals - Used only by FunctionProtoType, put here to pack with the
/// other bitfields.
- /// The qualifiers are part of FunctionTypeProto because...
+ /// The qualifiers are part of FunctionProtoType because...
///
/// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type.
@@ -1133,10 +1105,10 @@ public:
static bool classof(const FunctionType *) { return true; }
};
-/// FunctionTypeNoProto - Represents a K&R-style 'int foo()' function, which has
+/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
/// no information available about its arguments.
-class FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode {
- FunctionTypeNoProto(QualType Result, QualType Canonical)
+class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
+ FunctionNoProtoType(QualType Result, QualType Canonical)
: FunctionType(FunctionNoProto, Result, false, 0, Canonical,
/*Dependent=*/false) {}
friend class ASTContext; // ASTContext creates these.
@@ -1155,7 +1127,7 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto;
}
- static bool classof(const FunctionTypeNoProto *) { return true; }
+ static bool classof(const FunctionNoProtoType *) { return true; }
protected:
virtual void EmitImpl(llvm::Serializer& S) const;
@@ -1163,10 +1135,10 @@ protected:
friend class Type;
};
-/// FunctionTypeProto - Represents a prototype with argument type info, e.g.
+/// FunctionProtoType - Represents a prototype with argument type info, e.g.
/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
/// arguments, not as having a single void argument.
-class FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
+class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
/// hasAnyDependentType - Determine whether there are any dependent
/// types within the arguments passed in.
static bool hasAnyDependentType(const QualType *ArgArray, unsigned numArgs) {
@@ -1177,7 +1149,7 @@ class FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
return false;
}
- FunctionTypeProto(QualType Result, const QualType *ArgArray, unsigned numArgs,
+ FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs,
bool isVariadic, unsigned typeQuals, QualType Canonical)
: FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
(Result->isDependentType() ||
@@ -1218,7 +1190,7 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto;
}
- static bool classof(const FunctionTypeProto *) { return true; }
+ static bool classof(const FunctionProtoType *) { return true; }
void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
@@ -1254,7 +1226,7 @@ public:
virtual void getAsStringInternal(std::string &InnerString) const;
- static bool classof(const Type *T) { return T->getTypeClass() == TypeName; }
+ static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
static bool classof(const TypedefType *) { return true; }
protected:
@@ -1263,18 +1235,18 @@ protected:
friend class Type;
};
-/// TypeOfExpr (GCC extension).
-class TypeOfExpr : public Type {
+/// TypeOfExprType (GCC extension).
+class TypeOfExprType : public Type {
Expr *TOExpr;
- TypeOfExpr(Expr *E, QualType can);
+ TypeOfExprType(Expr *E, QualType can);
friend class ASTContext; // ASTContext creates these.
public:
Expr *getUnderlyingExpr() const { return TOExpr; }
virtual void getAsStringInternal(std::string &InnerString) const;
- static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExp; }
- static bool classof(const TypeOfExpr *) { return true; }
+ static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
+ static bool classof(const TypeOfExprType *) { return true; }
protected:
virtual void EmitImpl(llvm::Serializer& S) const;
@@ -1286,7 +1258,7 @@ protected:
class TypeOfType : public Type {
QualType TOType;
TypeOfType(QualType T, QualType can)
- : Type(TypeOfTyp, can, T->isDependentType()), TOType(T) {
+ : Type(TypeOf, can, T->isDependentType()), TOType(T) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
}
friend class ASTContext; // ASTContext creates these.
@@ -1295,7 +1267,7 @@ public:
virtual void getAsStringInternal(std::string &InnerString) const;
- static bool classof(const Type *T) { return T->getTypeClass() == TypeOfTyp; }
+ static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
static bool classof(const TypeOfType *) { return true; }
protected:
@@ -1318,8 +1290,8 @@ protected:
// FIXME: We'll need the user to pass in information about whether
// this type is dependent or not, because we don't have enough
// information to compute it here.
- TagType(TagDecl *D, QualType can)
- : Type(Tagged, can, /*Dependent=*/false), decl(D, 0) {}
+ TagType(TypeClass TC, TagDecl *D, QualType can)
+ : Type(TC, can, /*Dependent=*/false), decl(D, 0) {}
public:
TagDecl *getDecl() const { return decl.getPointer(); }
@@ -1331,9 +1303,14 @@ public:
virtual void getAsStringInternal(std::string &InnerString) const;
- static bool classof(const Type *T) { return T->getTypeClass() == Tagged; }
+ static bool classof(const Type *T) {
+ return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
+ }
static bool classof(const TagType *) { return true; }
-
+ static bool classof(const RecordType *) { return true; }
+ static bool classof(const CXXRecordType *) { return true; }
+ static bool classof(const EnumType *) { return true; }
+
protected:
virtual void EmitImpl(llvm::Serializer& S) const;
static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
@@ -1345,7 +1322,9 @@ protected:
class RecordType : public TagType {
protected:
explicit RecordType(RecordDecl *D)
- : TagType(reinterpret_cast<TagDecl*>(D), QualType()) { }
+ : TagType(Record, reinterpret_cast<TagDecl*>(D), QualType()) { }
+ explicit RecordType(TypeClass TC, RecordDecl *D)
+ : TagType(TC, reinterpret_cast<TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -1373,7 +1352,7 @@ public:
/// isa/cast/dyncast to detect TagType objects of C++ structs/unions/classes.
class CXXRecordType : public RecordType {
explicit CXXRecordType(CXXRecordDecl *D)
- : RecordType(reinterpret_cast<RecordDecl*>(D)) { }
+ : RecordType(CXXRecord, reinterpret_cast<RecordDecl*>(D)) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -1392,7 +1371,7 @@ public:
/// to detect TagType objects of enums.
class EnumType : public TagType {
explicit EnumType(EnumDecl *D)
- : TagType(reinterpret_cast<TagDecl*>(D), QualType()) { }
+ : TagType(Enum, reinterpret_cast<TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these.
public:
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
new file mode 100644
index 0000000000..273475b041
--- /dev/null
+++ b/include/clang/AST/TypeNodes.def
@@ -0,0 +1,83 @@
+//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AST type info database. Each type node is
+// enumerated by providing its name (e.g., "Builtin" or "Enum") and
+// base class (e.g., "Type" or "TagType"). Depending on where in the
+// abstract syntax tree the type will show up, the enumeration uses
+// one of four different macros:
+//
+// TYPE(Class, Base) - A type that can show up anywhere in the AST,
+// and might be dependent, canonical, or non-canonical. All clients
+// will need to understand these types.
+//
+// ABSTRACT_TYPE(Class, Base) - An abstract class that shows up in
+// the type hierarchy but has no concrete instances.
+//
+// NON_CANONICAL_TYPE(Class, Base) - A type that can show up
+// anywhere in the AST but will never be a part of a canonical
+// type. Clients that only need to deal with canonical types
+// (ignoring, e.g., typedefs and other type alises used for
+// pretty-printing) can ignore these types.
+//
+// DEPENDENT_TYPE(Class, Base) - A type that will only show up
+// within a C++ template that has not been instantiated, e.g., a
+// type that is always dependent. Clients that do not need to deal
+// with uninstantiated C++ templates can ignore these types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ABSTRACT_TYPE
+# define ABSTRACT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef NON_CANONICAL_TYPE
+# define NON_CANONICAL_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+#ifndef DEPENDENT_TYPE
+# define DEPENDENT_TYPE(Class, Base) TYPE(Class, Base)
+#endif
+
+TYPE(ExtQual, Type)
+TYPE(Builtin, Type)
+TYPE(FixedWidthInt, Type)
+TYPE(Complex, Type)
+TYPE(Pointer, Type)
+TYPE(Blo