diff options
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(BlockPointer, Type) +TYPE(Reference, Type) +TYPE(MemberPointer, Type) +ABSTRACT_TYPE(Array, Type) +TYPE(ConstantArray, ArrayType) +TYPE(IncompleteArray, ArrayType) +TYPE(VariableArray, ArrayType) +DEPENDENT_TYPE(DependentSizedArray, ArrayType) +TYPE(Vector, Type) +TYPE(ExtVector, VectorType) +ABSTRACT_TYPE(Function, Type) +TYPE(FunctionProto, Function) +TYPE(FunctionNoProto, Function) +NON_CANONICAL_TYPE(Typedef, Type) +NON_CANONICAL_TYPE(TypeOfExpr, Type) +NON_CANONICAL_TYPE(TypeOf, Type) +ABSTRACT_TYPE(Tag, Type) +TYPE(Record, TagType) +TYPE(CXXRecord, RecordType) // FIXME: kill this one +TYPE(Enum, TagType) +DEPENDENT_TYPE(TemplateTypeParm, Type) +NON_CANONICAL_TYPE(ClassTemplateSpecialization, Type) +TYPE(ObjCInterface, Type) +TYPE(ObjCQualifiedInterface, ObjCInterfaceType) +TYPE(ObjCQualifiedId, Type) +TYPE(ObjCQualifiedClass, Type) + +#undef DEPENDENT_TYPE +#undef NON_CANONICAL_TYPE +#undef ABSTRACT_TYPE +#undef TYPE diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 4febc3ba91..dd996bbbf1 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -545,7 +545,7 @@ protected: NodeSet& Dst); |