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...

llvm-svn: 65591
This commit is contained in:
Douglas Gregor 2009-02-26 23:50:07 +00:00
parent 007cb026c9
commit deaad8cc34
34 changed files with 417 additions and 303 deletions

View File

@ -227,7 +227,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
std::string Proto = FD->getNameAsString(); std::string Proto = FD->getNameAsString();
const FunctionType *AFT = FD->getType()->getAsFunctionType(); const FunctionType *AFT = FD->getType()->getAsFunctionType();
if (const FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(AFT)) { if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT)) {
Proto += "("; Proto += "(";
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) { for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
if (i) Proto += ", "; if (i) Proto += ", ";
@ -244,7 +244,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) {
} }
Proto += ")"; Proto += ")";
} else { } else {
assert(isa<FunctionTypeNoProto>(AFT)); assert(isa<FunctionNoProtoType>(AFT));
Proto += "()"; Proto += "()";
} }

View File

@ -141,7 +141,7 @@ public:
void RewriteProtocolDecl(ObjCProtocolDecl *PDecl); void RewriteProtocolDecl(ObjCProtocolDecl *PDecl);
void RewriteMethodDecl(ObjCMethodDecl *MDecl); void RewriteMethodDecl(ObjCMethodDecl *MDecl);
void RewriteFunctionTypeProto(QualType funcType, NamedDecl *D); void RewriteFunctionProtoType(QualType funcType, NamedDecl *D);
void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
void RewriteCastExpr(CastExpr *CE); void RewriteCastExpr(CastExpr *CE);
@ -370,12 +370,12 @@ std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i,
BlockDecl *BD = CE->getBlockDecl(); BlockDecl *BD = CE->getBlockDecl();
if (isa<FunctionTypeNoProto>(AFT)) { if (isa<FunctionNoProtoType>(AFT)) {
S += "()"; S += "()";
} else if (BD->param_empty()) { } else if (BD->param_empty()) {
S += "(" + StructRef + " *__cself)"; S += "(" + StructRef + " *__cself)";
} else { } else {
const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT); const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
assert(FT && "SynthesizeBlockFunc: No function proto"); assert(FT && "SynthesizeBlockFunc: No function proto");
S += '('; S += '(';
// first add the implicit argument. // first add the implicit argument.
@ -689,7 +689,7 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
assert(CPT && "RewriteBlockClass: Bad type"); assert(CPT && "RewriteBlockClass: Bad type");
const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType(); const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType();
assert(FT && "RewriteBlockClass: Bad type"); 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. // FTP will be null for closures that don't take arguments.
// Build a closure call - start with a paren expr to enforce precedence. // 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 += "(" + Exp->getType().getAsString() + "(*)";
BlockCall += "(struct __block_impl *"; BlockCall += "(struct __block_impl *";
if (FTP) { 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) E = FTP->arg_type_end(); I && (I != E); ++I)
BlockCall += ", " + (*I).getAsString(); BlockCall += ", " + (*I).getAsString();
} }
@ -803,17 +803,17 @@ void RewriteBlocks::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
} }
bool RewriteBlocks::PointerTypeTakesAnyBlockArguments(QualType QT) { bool RewriteBlocks::PointerTypeTakesAnyBlockArguments(QualType QT) {
const FunctionTypeProto *FTP; const FunctionProtoType *FTP;
const PointerType *PT = QT->getAsPointerType(); const PointerType *PT = QT->getAsPointerType();
if (PT) { if (PT) {
FTP = PT->getPointeeType()->getAsFunctionTypeProto(); FTP = PT->getPointeeType()->getAsFunctionProtoType();
} else { } else {
const BlockPointerType *BPT = QT->getAsBlockPointerType(); const BlockPointerType *BPT = QT->getAsBlockPointerType();
assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
FTP = BPT->getPointeeType()->getAsFunctionTypeProto(); FTP = BPT->getPointeeType()->getAsFunctionProtoType();
} }
if (FTP) { 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) E = FTP->arg_type_end(); I != E; ++I)
if (isBlockPointerType(*I)) if (isBlockPointerType(*I))
return true; return true;
@ -1049,9 +1049,9 @@ Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) {
return S; return S;
} }
void RewriteBlocks::RewriteFunctionTypeProto(QualType funcType, NamedDecl *D) { void RewriteBlocks::RewriteFunctionProtoType(QualType funcType, NamedDecl *D) {
if (FunctionTypeProto *fproto = dyn_cast<FunctionTypeProto>(funcType)) { if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
for (FunctionTypeProto::arg_type_iterator I = fproto->arg_type_begin(), for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
E = fproto->arg_type_end(); I && (I != E); ++I) E = fproto->arg_type_end(); I && (I != E); ++I)
if (isBlockPointerType(*I)) { if (isBlockPointerType(*I)) {
// All the args are checked/rewritten. Don't call twice! // 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) { void RewriteBlocks::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
const PointerType *PT = funcType->getAsPointerType(); const PointerType *PT = funcType->getAsPointerType();
if (PT && PointerTypeTakesAnyBlockArguments(funcType)) if (PT && PointerTypeTakesAnyBlockArguments(funcType))
RewriteFunctionTypeProto(PT->getPointeeType(), ND); RewriteFunctionProtoType(PT->getPointeeType(), ND);
} }
/// HandleDeclInMainFile - This is called for each top-level decl defined in the /// 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 // Since function prototypes don't have ParmDecl's, we check the function
// prototype. This enables us to rewrite function declarations and // prototype. This enables us to rewrite function declarations and
// definitions using the same code. // definitions using the same code.
RewriteFunctionTypeProto(FD->getType(), FD); RewriteFunctionProtoType(FD->getType(), FD);
if (Stmt *Body = FD->getBody()) { if (Stmt *Body = FD->getBody()) {
CurFunctionDef = FD; CurFunctionDef = FD;

View File

@ -311,7 +311,7 @@ namespace {
void SynthesizeMetaDataIntoBuffer(std::string &Result); void SynthesizeMetaDataIntoBuffer(std::string &Result);
// Block rewriting. // Block rewriting.
void RewriteBlocksInFunctionTypeProto(QualType funcType, NamedDecl *D); void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND); void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
void InsertBlockLiteralsWithinFunction(FunctionDecl *FD); void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
@ -371,10 +371,10 @@ namespace {
}; };
} }
void RewriteObjC::RewriteBlocksInFunctionTypeProto(QualType funcType, void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
NamedDecl *D) { NamedDecl *D) {
if (FunctionTypeProto *fproto = dyn_cast<FunctionTypeProto>(funcType)) { if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
for (FunctionTypeProto::arg_type_iterator I = fproto->arg_type_begin(), for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
E = fproto->arg_type_end(); I && (I != E); ++I) E = fproto->arg_type_end(); I && (I != E); ++I)
if (isTopLevelBlockPointerType(*I)) { if (isTopLevelBlockPointerType(*I)) {
// All the args are checked/rewritten. Don't call twice! // 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) { void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
const PointerType *PT = funcType->getAsPointerType(); const PointerType *PT = funcType->getAsPointerType();
if (PT && PointerTypeTakesAnyBlockArguments(funcType)) if (PT && PointerTypeTakesAnyBlockArguments(funcType))
RewriteBlocksInFunctionTypeProto(PT->getPointeeType(), ND); RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
} }
static bool IsHeaderFile(const std::string &Filename) { static bool IsHeaderFile(const std::string &Filename) {
@ -956,7 +956,7 @@ void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
ResultStr += ")"; // close the precedence "scope" for "*". ResultStr += ")"; // close the precedence "scope" for "*".
// Now, emit the argument types (if any). // Now, emit the argument types (if any).
if (const FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(FPRetType)) { if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
ResultStr += "("; ResultStr += "(";
for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
if (i) ResultStr += ", "; if (i) ResultStr += ", ";
@ -1855,7 +1855,7 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
SourceLocation Loc; SourceLocation Loc;
QualType Type; QualType Type;
const FunctionTypeProto *proto = 0; const FunctionProtoType *proto = 0;
if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) { if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
Loc = VD->getLocation(); Loc = VD->getLocation();
Type = VD->getType(); Type = VD->getType();
@ -1866,7 +1866,7 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
// information (id<p>, C<p>*). The protocol references need to be rewritten! // information (id<p>, C<p>*). The protocol references need to be rewritten!
const FunctionType *funcType = FD->getType()->getAsFunctionType(); const FunctionType *funcType = FD->getType()->getAsFunctionType();
assert(funcType && "missing function type"); assert(funcType && "missing function type");
proto = dyn_cast<FunctionTypeProto>(funcType); proto = dyn_cast<FunctionProtoType>(funcType);
if (!proto) if (!proto)
return; return;
Type = proto->getResultType(); Type = proto->getResultType();
@ -3482,14 +3482,14 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
BlockDecl *BD = CE->getBlockDecl(); 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 // No user-supplied arguments. Still need to pass in a pointer to the
// block (to reference imported block decl refs). // block (to reference imported block decl refs).
S += "(" + StructRef + " *__cself)"; S += "(" + StructRef + " *__cself)";
} else if (BD->param_empty()) { } else if (BD->param_empty()) {
S += "(" + StructRef + " *__cself)"; S += "(" + StructRef + " *__cself)";
} else { } else {
const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT); const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
assert(FT && "SynthesizeBlockFunc: No function proto"); assert(FT && "SynthesizeBlockFunc: No function proto");
S += '('; S += '(';
// first add the implicit argument. // first add the implicit argument.
@ -3806,7 +3806,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
assert(CPT && "RewriteBlockClass: Bad type"); assert(CPT && "RewriteBlockClass: Bad type");
const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType(); const FunctionType *FT = CPT->getPointeeType()->getAsFunctionType();
assert(FT && "RewriteBlockClass: Bad type"); 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. // FTP will be null for closures that don't take arguments.
RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl, RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
@ -3820,7 +3820,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
// Push the block argument type. // Push the block argument type.
ArgTypes.push_back(PtrBlock); ArgTypes.push_back(PtrBlock);
if (FTP) { 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) { E = FTP->arg_type_end(); I && (I != E); ++I) {
QualType t = *I; QualType t = *I;
// Make sure we convert "t (^)(...)" to "t (*)(...)". // Make sure we convert "t (^)(...)" to "t (*)(...)".
@ -3951,17 +3951,17 @@ void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
} }
bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) { bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
const FunctionTypeProto *FTP; const FunctionProtoType *FTP;
const PointerType *PT = QT->getAsPointerType(); const PointerType *PT = QT->getAsPointerType();
if (PT) { if (PT) {
FTP = PT->getPointeeType()->getAsFunctionTypeProto(); FTP = PT->getPointeeType()->getAsFunctionProtoType();
} else { } else {
const BlockPointerType *BPT = QT->getAsBlockPointerType(); const BlockPointerType *BPT = QT->getAsBlockPointerType();
assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type"); assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
FTP = BPT->getPointeeType()->getAsFunctionTypeProto(); FTP = BPT->getPointeeType()->getAsFunctionProtoType();
} }
if (FTP) { 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) E = FTP->arg_type_end(); I != E; ++I)
if (isTopLevelBlockPointerType(*I)) if (isTopLevelBlockPointerType(*I))
return true; return true;
@ -4061,7 +4061,7 @@ void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) { FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
IdentifierInfo *ID = &Context->Idents.get(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(), return FunctionDecl::Create(*Context, TUDecl,SourceLocation(),
ID, FType, FunctionDecl::Extern, false, ID, FType, FunctionDecl::Extern, false,
false); false);
@ -4424,7 +4424,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
// Since function prototypes don't have ParmDecl's, we check the function // Since function prototypes don't have ParmDecl's, we check the function
// prototype. This enables us to rewrite function declarations and // prototype. This enables us to rewrite function declarations and
// definitions using the same code. // definitions using the same code.
RewriteBlocksInFunctionTypeProto(FD->getType(), FD); RewriteBlocksInFunctionProtoType(FD->getType(), FD);
if (Stmt *Body = FD->getBody()) { if (Stmt *Body = FD->getBody()) {
CurFunctionDef = FD; CurFunctionDef = FD;

View File

@ -66,8 +66,8 @@ class ASTContext {
std::vector<VariableArrayType*> VariableArrayTypes; std::vector<VariableArrayType*> VariableArrayTypes;
std::vector<DependentSizedArrayType*> DependentSizedArrayTypes; std::vector<DependentSizedArrayType*> DependentSizedArrayTypes;
llvm::FoldingSet<VectorType> VectorTypes; llvm::FoldingSet<VectorType> VectorTypes;
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos; llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos; llvm::FoldingSet<FunctionProtoType> FunctionProtoTypes;
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes; llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
llvm::FoldingSet<ClassTemplateSpecializationType> llvm::FoldingSet<ClassTemplateSpecializationType>
ClassTemplateSpecializationTypes; ClassTemplateSpecializationTypes;
@ -251,9 +251,9 @@ public:
/// type. /// type.
QualType getExtVectorType(QualType VectorType, unsigned NumElts); 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 /// getFunctionType - Return a normal function type with a typed argument
/// list. isVariadic indicates whether the argument list includes '...'. /// list. isVariadic indicates whether the argument list includes '...'.
@ -293,7 +293,7 @@ public:
/// getTypeOfType - GCC extension. /// getTypeOfType - GCC extension.
QualType getTypeOfExpr(Expr *e); QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t); QualType getTypeOfType(QualType t);
/// getTagDeclType - Return the unique reference to the type for the /// getTagDeclType - Return the unique reference to the type for the

View File

@ -419,7 +419,7 @@ public:
QualType getThisType(ASTContext &C) const; QualType getThisType(ASTContext &C) const;
unsigned getTypeQualifiers() const { unsigned getTypeQualifiers() const {
return getType()->getAsFunctionTypeProto()->getTypeQuals(); return getType()->getAsFunctionProtoType()->getTypeQuals();
} }
// Implement isa/cast/dyncast/etc. // Implement isa/cast/dyncast/etc.

View File

@ -45,32 +45,11 @@ namespace clang {
class Expr; class Expr;
class Stmt; class Stmt;
class SourceLocation; 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 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 /// 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 /// 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 /// 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 /// 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 /// there is a PointerType that represents 'int*', which, like 'int', is
/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical /// 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*'. /// is also 'int*'.
/// ///
/// Non-canonical types are useful for emitting diagnostics, without losing /// Non-canonical types are useful for emitting diagnostics, without losing
@ -261,17 +240,10 @@ namespace clang {
class Type { class Type {
public: public:
enum TypeClass { enum TypeClass {
Builtin, Complex, Pointer, Reference, MemberPointer, #define TYPE(Class, Base) Class,
ConstantArray, VariableArray, IncompleteArray, DependentSizedArray, #define ABSTRACT_TYPE(Class, Base)
Vector, ExtVector, #include "clang/AST/TypeNodes.def"
FunctionNoProto, FunctionProto, TagFirst = Record, TagLast = Enum
TypeName, Tagged, ExtQual,
TemplateTypeParm, ClassTemplateSpecialization,
ObjCInterface, ObjCQualifiedInterface,
ObjCQualifiedId, ObjCQualifiedClass,
TypeOfExp, TypeOfTyp, // GNU typeof extension.
BlockPointer, // C extension
FixedWidthInt
}; };
private: private:
@ -401,8 +373,8 @@ public:
// the best type we can. // the best type we can.
const BuiltinType *getAsBuiltinType() const; const BuiltinType *getAsBuiltinType() const;
const FunctionType *getAsFunctionType() const; const FunctionType *getAsFunctionType() const;
const FunctionTypeNoProto *getAsFunctionTypeNoProto() const; const FunctionNoProtoType *getAsFunctionNoProtoType() const;
const FunctionTypeProto *getAsFunctionTypeProto() const; const FunctionProtoType *getAsFunctionProtoType() const;
const PointerType *getAsPointerType() const; const PointerType *getAsPointerType() const;
const BlockPointerType *getAsBlockPointerType() const; const BlockPointerType *getAsBlockPointerType() const;
const ReferenceType *getAsReferenceType() const; const ReferenceType *getAsReferenceType() const;
@ -1096,16 +1068,16 @@ public:
}; };
/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base /// 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 { class FunctionType : public Type {
/// SubClassData - This field is owned by the subclass, put here to pack /// SubClassData - This field is owned by the subclass, put here to pack
/// tightly with the ivars in Type. /// tightly with the ivars in Type.
bool SubClassData : 1; 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. /// 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 /// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type. /// cv-qualifier-seq, [...], are part of the function type.
@ -1133,10 +1105,10 @@ public:
static bool classof(const FunctionType *) { return true; } 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. /// no information available about its arguments.
class FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode { class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionTypeNoProto(QualType Result, QualType Canonical) FunctionNoProtoType(QualType Result, QualType Canonical)
: FunctionType(FunctionNoProto, Result, false, 0, Canonical, : FunctionType(FunctionNoProto, Result, false, 0, Canonical,
/*Dependent=*/false) {} /*Dependent=*/false) {}
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.
@ -1155,7 +1127,7 @@ public:
static bool classof(const Type *T) { static bool classof(const Type *T) {
return T->getTypeClass() == FunctionNoProto; return T->getTypeClass() == FunctionNoProto;
} }
static bool classof(const FunctionTypeNoProto *) { return true; } static bool classof(const FunctionNoProtoType *) { return true; }
protected: protected:
virtual void EmitImpl(llvm::Serializer& S) const; virtual void EmitImpl(llvm::Serializer& S) const;
@ -1163,10 +1135,10 @@ protected:
friend class Type; 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 /// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
/// arguments, not as having a single void argument. /// 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 /// hasAnyDependentType - Determine whether there are any dependent
/// types within the arguments passed in. /// types within the arguments passed in.
static bool hasAnyDependentType(const QualType *ArgArray, unsigned numArgs) { static bool hasAnyDependentType(const QualType *ArgArray, unsigned numArgs) {
@ -1177,7 +1149,7 @@ class FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
return false; return false;
} }
FunctionTypeProto(QualType Result, const QualType *ArgArray, unsigned numArgs, FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs,
bool isVariadic, unsigned typeQuals, QualType Canonical) bool isVariadic, unsigned typeQuals, QualType Canonical)
: FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical, : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
(Result->isDependentType() || (Result->isDependentType() ||
@ -1218,7 +1190,7 @@ public:
static bool classof(const Type *T) { static bool classof(const Type *T) {
return T->getTypeClass() == FunctionProto; return T->getTypeClass() == FunctionProto;
} }
static bool classof(const FunctionTypeProto *) { return true; } static bool classof(const FunctionProtoType *) { return true; }
void Profile(llvm::FoldingSetNodeID &ID); void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
@ -1254,7 +1226,7 @@ public:
virtual void getAsStringInternal(std::string &InnerString) const; 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; } static bool classof(const TypedefType *) { return true; }
protected: protected:
@ -1263,18 +1235,18 @@ protected:
friend class Type; friend class Type;
}; };
/// TypeOfExpr (GCC extension). /// TypeOfExprType (GCC extension).
class TypeOfExpr : public Type { class TypeOfExprType : public Type {
Expr *TOExpr; Expr *TOExpr;
TypeOfExpr(Expr *E, QualType can); TypeOfExprType(Expr *E, QualType can);
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.
public: public:
Expr *getUnderlyingExpr() const { return TOExpr; } Expr *getUnderlyingExpr() const { return TOExpr; }
virtual void getAsStringInternal(std::string &InnerString) const; virtual void getAsStringInternal(std::string &InnerString) const;
static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExp; } static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
static bool classof(const TypeOfExpr *) { return true; } static bool classof(const TypeOfExprType *) { return true; }
protected: protected:
virtual void EmitImpl(llvm::Serializer& S) const; virtual void EmitImpl(llvm::Serializer& S) const;
@ -1286,7 +1258,7 @@ protected:
class TypeOfType : public Type { class TypeOfType : public Type {
QualType TOType; QualType TOType;
TypeOfType(QualType T, QualType can) 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"); assert(!isa<TypedefType>(can) && "Invalid canonical type");
} }
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.
@ -1295,7 +1267,7 @@ public:
virtual void getAsStringInternal(std::string &InnerString) const; 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; } static bool classof(const TypeOfType *) { return true; }
protected: protected:
@ -1318,8 +1290,8 @@ protected:
// FIXME: We'll need the user to pass in information about whether // FIXME: We'll need the user to pass in information about whether
// this type is dependent or not, because we don't have enough // this type is dependent or not, because we don't have enough
// information to compute it here. // information to compute it here.
TagType(TagDecl *D, QualType can) TagType(TypeClass TC, TagDecl *D, QualType can)
: Type(Tagged, can, /*Dependent=*/false), decl(D, 0) {} : Type(TC, can, /*Dependent=*/false), decl(D, 0) {}
public: public:
TagDecl *getDecl() const { return decl.getPointer(); } TagDecl *getDecl() const { return decl.getPointer(); }
@ -1331,9 +1303,14 @@ public:
virtual void getAsStringInternal(std::string &InnerString) const; 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 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: protected:
virtual void EmitImpl(llvm::Serializer& S) const; virtual void EmitImpl(llvm::Serializer& S) const;
static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D); static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D);
@ -1345,7 +1322,9 @@ protected:
class RecordType : public TagType { class RecordType : public TagType {
protected: protected:
explicit RecordType(RecordDecl *D) 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. friend class ASTContext; // ASTContext creates these.
public: public:
@ -1373,7 +1352,7 @@ public:
/// isa/cast/dyncast to detect TagType objects of C++ structs/unions/classes. /// isa/cast/dyncast to detect TagType objects of C++ structs/unions/classes.
class CXXRecordType : public RecordType { class CXXRecordType : public RecordType {
explicit CXXRecordType(CXXRecordDecl *D) explicit CXXRecordType(CXXRecordDecl *D)
: RecordType(reinterpret_cast<RecordDecl*>(D)) { } : RecordType(CXXRecord, reinterpret_cast<RecordDecl*>(D)) { }
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.
public: public:
@ -1392,7 +1371,7 @@ public:
/// to detect TagType objects of enums. /// to detect TagType objects of enums.
class EnumType : public TagType { class EnumType : public TagType {
explicit EnumType(EnumDecl *D) explicit EnumType(EnumDecl *D)
: TagType(reinterpret_cast<TagDecl*>(D), QualType()) { } : TagType(Enum, reinterpret_cast<TagDecl*>(D), QualType()) { }
friend class ASTContext; // ASTContext creates these. friend class ASTContext; // ASTContext creates these.
public: public:

View File

@ -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

View File

@ -545,7 +545,7 @@ protected:
NodeSet& Dst); NodeSet& Dst);
void VisitCallRec(CallExpr* CE, NodeTy* Pred, void VisitCallRec(CallExpr* CE, NodeTy* Pred,
CallExpr::arg_iterator AI, CallExpr::arg_iterator AE, CallExpr::arg_iterator AI, CallExpr::arg_iterator AE,
NodeSet& Dst, const FunctionTypeProto *, NodeSet& Dst, const FunctionProtoType *,
unsigned ParamIdx = 0); unsigned ParamIdx = 0);
/// VisitCast - Transfer function logic for all casts (implicit and explicit). /// VisitCast - Transfer function logic for all casts (implicit and explicit).

View File

@ -91,7 +91,7 @@ void ASTContext::PrintStats() const {
unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0; unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0; unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0;
unsigned NumObjCQualifiedIds = 0; unsigned NumObjCQualifiedIds = 0;
unsigned NumTypeOfTypes = 0, NumTypeOfExprs = 0; unsigned NumTypeOfTypes = 0, NumTypeOfExprTypes = 0;
for (unsigned i = 0, e = Types.size(); i != e; ++i) { for (unsigned i = 0, e = Types.size(); i != e; ++i) {
Type *T = Types[i]; Type *T = Types[i];
@ -111,9 +111,9 @@ void ASTContext::PrintStats() const {
++NumArray; ++NumArray;
else if (isa<VectorType>(T)) else if (isa<VectorType>(T))
++NumVector; ++NumVector;
else if (isa<FunctionTypeNoProto>(T)) else if (isa<FunctionNoProtoType>(T))
++NumFunctionNP; ++NumFunctionNP;
else if (isa<FunctionTypeProto>(T)) else if (isa<FunctionProtoType>(T))
++NumFunctionP; ++NumFunctionP;
else if (isa<TypedefType>(T)) else if (isa<TypedefType>(T))
++NumTypeName; ++NumTypeName;
@ -134,8 +134,8 @@ void ASTContext::PrintStats() const {
++NumObjCQualifiedIds; ++NumObjCQualifiedIds;
else if (isa<TypeOfType>(T)) else if (isa<TypeOfType>(T))
++NumTypeOfTypes; ++NumTypeOfTypes;
else if (isa<TypeOfExpr>(T)) else if (isa<TypeOfExprType>(T))
++NumTypeOfExprs; ++NumTypeOfExprTypes;
else { else {
QualType(T, 0).dump(); QualType(T, 0).dump();
assert(0 && "Unknown type!"); assert(0 && "Unknown type!");
@ -164,16 +164,16 @@ void ASTContext::PrintStats() const {
fprintf(stderr, " %d protocol qualified id types\n", fprintf(stderr, " %d protocol qualified id types\n",
NumObjCQualifiedIds); NumObjCQualifiedIds);
fprintf(stderr, " %d typeof types\n", NumTypeOfTypes); fprintf(stderr, " %d typeof types\n", NumTypeOfTypes);
fprintf(stderr, " %d typeof exprs\n", NumTypeOfExprs); fprintf(stderr, " %d typeof exprs\n", NumTypeOfExprTypes);
fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+ fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+ NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+ NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
NumMemberPointer*sizeof(MemberPointerType)+ NumMemberPointer*sizeof(MemberPointerType)+
NumFunctionP*sizeof(FunctionTypeProto)+ NumFunctionP*sizeof(FunctionProtoType)+
NumFunctionNP*sizeof(FunctionTypeNoProto)+ NumFunctionNP*sizeof(FunctionNoProtoType)+
NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+ NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+
NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprs*sizeof(TypeOfExpr))); NumTypeOfTypes*sizeof(TypeOfType)+NumTypeOfExprTypes*sizeof(TypeOfExprType)));
} }
@ -293,15 +293,20 @@ ASTContext::getTypeInfo(const Type *T) {
uint64_t Width; uint64_t Width;
unsigned Align; unsigned Align;
switch (T->getTypeClass()) { switch (T->getTypeClass()) {
case Type::TypeName: assert(0 && "Not a canonical type!"); #define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
assert(false && "Should not see non-canonical or dependent types");
break;
case Type::FunctionNoProto: case Type::FunctionNoProto:
case Type::FunctionProto: case Type::FunctionProto:
default: case Type::IncompleteArray:
assert(0 && "Incomplete types have no size!"); assert(0 && "Incomplete types have no size!");
case Type::VariableArray: case Type::VariableArray:
assert(0 && "VLAs not implemented yet!"); assert(0 && "VLAs not implemented yet!");
case Type::DependentSizedArray:
assert(0 && "Dependently-sized arrays don't have a known size");
case Type::ConstantArray: { case Type::ConstantArray: {
const ConstantArrayType *CAT = cast<ConstantArrayType>(T); const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
@ -390,6 +395,7 @@ ASTContext::getTypeInfo(const Type *T) {
return getTypeInfo(QualType(cast<ExtQualType>(T)->getBaseType(), 0)); return getTypeInfo(QualType(cast<ExtQualType>(T)->getBaseType(), 0));
case Type::ObjCQualifiedId: case Type::ObjCQualifiedId:
case Type::ObjCQualifiedClass: case Type::ObjCQualifiedClass:
case Type::ObjCQualifiedInterface:
Width = Target.getPointerWidth(0); Width = Target.getPointerWidth(0);
Align = Target.getPointerAlign(0); Align = Target.getPointerAlign(0);
break; break;
@ -441,7 +447,9 @@ ASTContext::getTypeInfo(const Type *T) {
Align = Layout.getAlignment(); Align = Layout.getAlignment();
break; break;
} }
case Type::Tagged: { case Type::Record:
case Type::CXXRecord:
case Type::Enum: {
const TagType *TT = cast<TagType>(T); const TagType *TT = cast<TagType>(T);
if (TT->getDecl()->isInvalidDecl()) { if (TT->getDecl()->isInvalidDecl()) {
@ -1127,32 +1135,32 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
return QualType(New, 0); return QualType(New, 0);
} }
/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'. /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
/// ///
QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) { QualType ASTContext::getFunctionNoProtoType(QualType ResultTy) {
// Unique functions, to guarantee there is only one function of a particular // Unique functions, to guarantee there is only one function of a particular
// structure. // structure.
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
FunctionTypeNoProto::Profile(ID, ResultTy); FunctionNoProtoType::Profile(ID, ResultTy);
void *InsertPos = 0; void *InsertPos = 0;
if (FunctionTypeNoProto *FT = if (FunctionNoProtoType *FT =
FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos)) FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(FT, 0); return QualType(FT, 0);
QualType Canonical; QualType Canonical;
if (!ResultTy->isCanonical()) { if (!ResultTy->isCanonical()) {
Canonical = getFunctionTypeNoProto(getCanonicalType(ResultTy)); Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy));
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
FunctionTypeNoProto *NewIP = FunctionNoProtoType *NewIP =
FunctionTypeNoProtos.FindNodeOrInsertPos(ID, InsertPos); FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
} }
FunctionTypeNoProto *New =new(*this,8)FunctionTypeNoProto(ResultTy,Canonical); FunctionNoProtoType *New =new(*this,8)FunctionNoProtoType(ResultTy,Canonical);
Types.push_back(New); Types.push_back(New);
FunctionTypeNoProtos.InsertNode(New, InsertPos); FunctionNoProtoTypes.InsertNode(New, InsertPos);
return QualType(New, 0); return QualType(New, 0);
} }
@ -1164,12 +1172,12 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
// Unique functions, to guarantee there is only one function of a particular // Unique functions, to guarantee there is only one function of a particular
// structure. // structure.
llvm::FoldingSetNodeID ID; llvm::FoldingSetNodeID ID;
FunctionTypeProto::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic, FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic,
TypeQuals); TypeQuals);
void *InsertPos = 0; void *InsertPos = 0;
if (FunctionTypeProto *FTP = if (FunctionProtoType *FTP =
FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos)) FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(FTP, 0); return QualType(FTP, 0);
// Determine whether the type being created is already canonical or not. // Determine whether the type being created is already canonical or not.
@ -1191,20 +1199,20 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
isVariadic, TypeQuals); isVariadic, TypeQuals);
// Get the new insert position for the node we care about. // Get the new insert position for the node we care about.
FunctionTypeProto *NewIP = FunctionProtoType *NewIP =
FunctionTypeProtos.FindNodeOrInsertPos(ID, InsertPos); FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
} }
// FunctionTypeProto objects are allocated with extra bytes after them // FunctionProtoType objects are allocated with extra bytes after them
// for a variable size array (for parameter types) at the end of them. // for a variable size array (for parameter types) at the end of them.
FunctionTypeProto *FTP = FunctionProtoType *FTP =
(FunctionTypeProto*)Allocate(sizeof(FunctionTypeProto) + (FunctionProtoType*)Allocate(sizeof(FunctionProtoType) +
NumArgs*sizeof(QualType), 8); NumArgs*sizeof(QualType), 8);
new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic, new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic,
TypeQuals, Canonical); TypeQuals, Canonical);
Types.push_back(FTP); Types.push_back(FTP);
FunctionTypeProtos.InsertNode(FTP, InsertPos); FunctionProtoTypes.InsertNode(FTP, InsertPos);
return QualType(FTP, 0); return QualType(FTP, 0);
} }
@ -1252,7 +1260,7 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) {
if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
QualType Canonical = getCanonicalType(Decl->getUnderlyingType()); QualType Canonical = getCanonicalType(Decl->getUnderlyingType());
Decl->TypeForDecl = new(*this,8) TypedefType(Type::TypeName, Decl, Canonical); Decl->TypeForDecl = new(*this,8) TypedefType(Type::Typedef, Decl, Canonical);
Types.push_back(Decl->TypeForDecl); Types.push_back(Decl->TypeForDecl);
return QualType(Decl->TypeForDecl, 0); return QualType(Decl->TypeForDecl, 0);
} }
@ -1401,14 +1409,14 @@ QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols,
return QualType(QType, 0); return QualType(QType, 0);
} }
/// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique /// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
/// TypeOfExpr AST's (since expression's are never shared). For example, /// TypeOfExprType AST's (since expression's are never shared). For example,
/// multiple declarations that refer to "typeof(x)" all contain different /// multiple declarations that refer to "typeof(x)" all contain different
/// DeclRefExpr's. This doesn't effect the type checker, since it operates /// DeclRefExpr's. This doesn't effect the type checker, since it operates
/// on canonical type's (which are always unique). /// on canonical type's (which are always unique).
QualType ASTContext::getTypeOfExpr(Expr *tofExpr) { QualType ASTContext::getTypeOfExprType(Expr *tofExpr) {
QualType Canonical = getCanonicalType(tofExpr->getType()); QualType Canonical = getCanonicalType(tofExpr->getType());
TypeOfExpr *toe = new (*this,8) TypeOfExpr(tofExpr, Canonical); TypeOfExprType *toe = new (*this,8) TypeOfExprType(tofExpr, Canonical);
Types.push_back(toe); Types.push_back(toe);
return QualType(toe, 0); return QualType(toe, 0);
} }
@ -2458,8 +2466,8 @@ QualType::GCAttrTypes ASTContext::getObjCGCAttrKind(const QualType &Ty) const {
bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) { bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
const FunctionType *lbase = lhs->getAsFunctionType(); const FunctionType *lbase = lhs->getAsFunctionType();
const FunctionType *rbase = rhs->getAsFunctionType(); const FunctionType *rbase = rhs->getAsFunctionType();
const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase); const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase); const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
if (lproto && rproto) if (lproto && rproto)
return !mergeTypes(lhs, rhs).isNull(); return !mergeTypes(lhs, rhs).isNull();
return false; return false;
@ -2561,8 +2569,8 @@ bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS) {
QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
const FunctionType *lbase = lhs->getAsFunctionType(); const FunctionType *lbase = lhs->getAsFunctionType();
const FunctionType *rbase = rhs->getAsFunctionType(); const FunctionType *rbase = rhs->getAsFunctionType();
const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase); const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase); const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
bool allLTypes = true; bool allLTypes = true;
bool allRTypes = true; bool allRTypes = true;
@ -2611,7 +2619,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
if (lproto) allRTypes = false; if (lproto) allRTypes = false;
if (rproto) allLTypes = false; if (rproto) allLTypes = false;
const FunctionTypeProto *proto = lproto ? lproto : rproto; const FunctionProtoType *proto = lproto ? lproto : rproto;
if (proto) { if (proto) {
if (proto->isVariadic()) return QualType(); if (proto->isVariadic()) return QualType();
// Check that the types are compatible with the types that // Check that the types are compatible with the types that
@ -2636,7 +2644,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
if (allLTypes) return lhs; if (allLTypes) return lhs;
if (allRTypes) return rhs; if (allRTypes) return rhs;
return getFunctionTypeNoProto(retType); return getFunctionNoProtoType(retType);
} }
QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
@ -2739,6 +2747,27 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
// The canonical type classes match. // The canonical type classes match.
switch (LHSClass) { switch (LHSClass) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
assert(false && "Non-canonical and dependent types shouldn't get here");
return QualType();
case Type::Reference:
case Type::MemberPointer:
assert(false && "C++ should never be in mergeTypes");
return QualType();
case Type::IncompleteArray:
case Type::VariableArray:
case Type::FunctionProto:
case Type::ExtVector:
case Type::ObjCQualifiedInterface:
assert(false && "Types are eliminated above");
return QualType();
case Type::Pointer: case Type::Pointer:
{ {
// Merge two pointer types, while trying to preserve typedef info // Merge two pointer types, while trying to preserve typedef info
@ -2808,7 +2837,9 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
} }
case Type::FunctionNoProto: case Type::FunctionNoProto:
return mergeFunctionTypes(LHS, RHS); return mergeFunctionTypes(LHS, RHS);
case Type::Tagged: case Type::Record:
case Type::CXXRecord:
case Type::Enum:
// FIXME: Why are these compatible? // FIXME: Why are these compatible?
if (isObjCIdStructType(LHS) && isObjCClassStructType(RHS)) return LHS; if (isObjCIdStructType(LHS) && isObjCClassStructType(RHS)) return LHS;
if (isObjCClassStructType(LHS) && isObjCIdStructType(RHS)) return LHS; if (isObjCClassStructType(LHS) && isObjCIdStructType(RHS)) return LHS;
@ -2836,10 +2867,9 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
case Type::ObjCQualifiedId: case Type::ObjCQualifiedId:
// Distinct qualified id's are not compatible. // Distinct qualified id's are not compatible.
return QualType(); return QualType();
default:
assert(0 && "unexpected type");
return QualType();
} }
return QualType();
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -264,7 +264,7 @@ QualType Builtin::Context::GetBuiltinType(unsigned id, ASTContext &Context,
// handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);". // handle untyped/variadic arguments "T c99Style();" or "T cppStyle(...);".
if (ArgTypes.size() == 0 && TypeStr[0] == '.') if (ArgTypes.size() == 0 && TypeStr[0] == '.')
return Context.getFunctionTypeNoProto(ResType); return Context.getFunctionNoProtoType(ResType);
return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(), return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(),
TypeStr[0] == '.', 0); TypeStr[0] == '.', 0);
} }

View File

@ -320,9 +320,9 @@ unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const {
// Helper function for FunctionDecl::getNumParams and FunctionDecl::setParams() // Helper function for FunctionDecl::getNumParams and FunctionDecl::setParams()
static unsigned getNumTypeParams(QualType T) { static unsigned getNumTypeParams(QualType T) {
const FunctionType *FT = T->getAsFunctionType(); const FunctionType *FT = T->getAsFunctionType();
if (isa<FunctionTypeNoProto>(FT)) if (isa<FunctionNoProtoType>(FT))
return 0; return 0;
return cast<FunctionTypeProto>(FT)->getNumArgs(); return cast<FunctionProtoType>(FT)->getNumArgs();
} }
unsigned FunctionDecl::getNumParams() const { unsigned FunctionDecl::getNumParams() const {

View File

@ -92,8 +92,8 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
if (Method->isStatic()) if (Method->isStatic())
continue; continue;
// TODO: Skip templates? Or is this implicitly done due to parameter types? // TODO: Skip templates? Or is this implicitly done due to parameter types?
const FunctionTypeProto *FnType = const FunctionProtoType *FnType =
Method->getType()->getAsFunctionTypeProto(); Method->getType()->getAsFunctionProtoType();
assert(FnType && "Overloaded operator has no prototype."); assert(FnType && "Overloaded operator has no prototype.");
// Don't assert on this; an invalid decl might have been left in the AST. // Don't assert on this; an invalid decl might have been left in the AST.
if (FnType->getNumArgs() != 1 || FnType->isVariadic()) if (FnType->getNumArgs() != 1 || FnType->isVariadic())
@ -146,7 +146,7 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
// We're interested specifically in copy assignment operators. // We're interested specifically in copy assignment operators.
// Unlike addedConstructor, this method is not called for implicit // Unlike addedConstructor, this method is not called for implicit
// declarations. // declarations.
const FunctionTypeProto *FnType = OpDecl->getType()->getAsFunctionTypeProto(); const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType();
assert(FnType && "Overloaded operator has no proto function type."); assert(FnType && "Overloaded operator has no proto function type.");
assert(FnType->getNumArgs() == 1 && !FnType->isVariadic()); assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
QualType ArgType = FnType->getArgType(0); QualType ArgType = FnType->getArgType(0);
@ -290,7 +290,7 @@ bool CXXConstructorDecl::isConvertingConstructor() const {
return false; return false;
return (getNumParams() == 0 && return (getNumParams() == 0 &&
getType()->getAsFunctionTypeProto()->isVariadic()) || getType()->getAsFunctionProtoType()->isVariadic()) ||
(getNumParams() == 1) || (getNumParams() == 1) ||
(getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0); (getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
} }

View File

@ -1193,9 +1193,9 @@ void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
const FunctionType *AFT = Node->getFunctionType(); const FunctionType *AFT = Node->getFunctionType();
if (isa<FunctionTypeNoProto>(AFT)) { if (isa<FunctionNoProtoType>(AFT)) {
OS << "()"; OS << "()";
} else if (!BD->param_empty() || cast<FunctionTypeProto>(AFT)->isVariadic()) { } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
OS << '('; OS << '(';
std::string ParamStr; std::string ParamStr;
for (BlockDecl::param_iterator AI = BD->param_begin(), for (BlockDecl::param_iterator AI = BD->param_begin(),
@ -1206,7 +1206,7 @@ void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
OS << ParamStr; OS << ParamStr;
} }
const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT); const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
if (FT->isVariadic()) { if (FT->isVariadic()) {
if (!BD->param_empty()) OS << ", "; if (!BD->param_empty()) OS << ", ";
OS << "..."; OS << "...";

View File

@ -78,7 +78,7 @@ const Type *Type::getArrayElementTypeNoTypeQual() const {
QualType Type::getDesugaredType() const { QualType Type::getDesugaredType() const {
if (const TypedefType *TDT = dyn_cast<TypedefType>(this)) if (const TypedefType *TDT = dyn_cast<TypedefType>(this))
return TDT->LookThroughTypedefs(); return TDT->LookThroughTypedefs();
if (const TypeOfExpr *TOE = dyn_cast<TypeOfExpr>(this)) if (const TypeOfExprType *TOE = dyn_cast<TypeOfExprType>(this))
return TOE->getUnderlyingExpr()->getType(); return TOE->getUnderlyingExpr()->getType();
if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this)) if (const TypeOfType *TOT = dyn_cast<TypeOfType>(this))
return TOT->getUnderlyingType(); return TOT->getUnderlyingType();
@ -118,9 +118,9 @@ bool Type::isDerivedType() const {
case FunctionProto: case FunctionProto:
case FunctionNoProto: case FunctionNoProto:
case Reference: case Reference:
case Record:
case CXXRecord:
return true; return true;
case Tagged:
return !cast<TagType>(CanonicalType)->getDecl()->isEnum();
default: default:
return false; return false;
} }
@ -216,12 +216,12 @@ const FunctionType *Type::getAsFunctionType() const {
return getDesugaredType()->getAsFunctionType(); return getDesugaredType()->getAsFunctionType();
} }
const FunctionTypeNoProto *Type::getAsFunctionTypeNoProto() const { const FunctionNoProtoType *Type::getAsFunctionNoProtoType() const {
return dyn_cast_or_null<FunctionTypeNoProto>(getAsFunctionType()); return dyn_cast_or_null<FunctionNoProtoType>(getAsFunctionType());
} }
const FunctionTypeProto *Type::getAsFunctionTypeProto() const { const FunctionProtoType *Type::getAsFunctionProtoType() const {
return dyn_cast_or_null<FunctionTypeProto>(getAsFunctionType()); return dyn_cast_or_null<FunctionProtoType>(getAsFunctionType());
} }
@ -742,7 +742,9 @@ bool Type::isIncompleteType() const {
// Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never // Void is the only incomplete builtin type. Per C99 6.2.5p19, it can never
// be completed. // be completed.
return isVoidType(); return isVoidType();
case Tagged: case Record:
case CXXRecord:
case Enum:
// A tagged type (struct/union/enum/class) is incomplete if the decl is a // A tagged type (struct/union/enum/class) is incomplete if the decl is a
// forward declaration, but not a full definition (C99 6.2.5p22). // forward declaration, but not a full definition (C99 6.2.5p22).
return !cast<TagType>(CanonicalType)->getDecl()->isDefinition(); return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
@ -778,14 +780,15 @@ bool Type::isPODType() const {
case ObjCQualifiedId: case ObjCQualifiedId:
return true; return true;
case Tagged: case Enum:
if (isEnumeralType()) return true;
return true;
if (CXXRecordDecl *RDecl = dyn_cast<CXXRecordDecl>( case Record:
cast<TagType>(CanonicalType)->getDecl()))
return RDecl->isPOD();
// C struct/union is POD. // C struct/union is POD.
return true; return true;
case CXXRecord:
return cast<CXXRecordType>(CanonicalType)->getDecl()->isPOD();
} }
} }
@ -832,7 +835,7 @@ const char *BuiltinType::getName() const {
} }
} }
void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result, void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
arg_type_iterator ArgTys, arg_type_iterator ArgTys,
unsigned NumArgs, bool isVariadic, unsigned NumArgs, bool isVariadic,
unsigned TypeQuals) { unsigned TypeQuals) {
@ -843,7 +846,7 @@ void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
ID.AddInteger(TypeQuals); ID.AddInteger(TypeQuals);
} }
void FunctionTypeProto::Profile(llvm::FoldingSetNodeID &ID) { void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(), Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(),
getTypeQuals()); getTypeQuals());
} }
@ -903,8 +906,8 @@ QualType TypedefType::LookThroughTypedefs() const {
} }
} }
TypeOfExpr::TypeOfExpr(Expr *E, QualType can) TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
: Type(TypeOfExp, can, E->isTypeDependent()), TOExpr(E) { : Type(TypeOfExpr, can, E->isTypeDependent()), TOExpr(E) {
assert(!isa<TypedefType>(can) && "Invalid canonical type"); assert(!isa<TypedefType>(can) && "Invalid canonical type");
} }
@ -1197,7 +1200,7 @@ void ExtVectorType::getAsStringInternal(std::string &S) const {
ElementType.getAsStringInternal(S); ElementType.getAsStringInternal(S);
} }
void TypeOfExpr::getAsStringInternal(std::string &InnerString) const { void TypeOfExprType::getAsStringInternal(std::string &InnerString) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(e) X'. if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(e) X'.
InnerString = ' ' + InnerString; InnerString = ' ' + InnerString;
std::string Str; std::string Str;
@ -1214,7 +1217,7 @@ void TypeOfType::getAsStringInternal(std::string &InnerString) const {
InnerString = "typeof(" + Tmp + ")" + InnerString; InnerString = "typeof(" + Tmp + ")" + InnerString;
} }
void FunctionTypeNoProto::getAsStringInternal(std::string &S) const { void FunctionNoProtoType::getAsStringInternal(std::string &S) const {
// If needed for precedence reasons, wrap the inner part in grouping parens. // If needed for precedence reasons, wrap the inner part in grouping parens.
if (!S.empty()) if (!S.empty())
S = "(" + S + ")"; S = "(" + S + ")";
@ -1223,7 +1226,7 @@ void FunctionTypeNoProto::getAsStringInternal(std::string &S) const {
getResultType().getAsStringInternal(S); getResultType().getAsStringInternal(S);
} }
void FunctionTypeProto::getAsStringInternal(std::string &S) const { void FunctionProtoType::getAsStringInternal(std::string &S) const {
// If needed for precedence reasons, wrap the inner part in grouping parens. // If needed for precedence reasons, wrap the inner part in grouping parens.
if (!S.empty()) if (!S.empty())
S = "(" + S + ")"; S = "(" + S + ")";

View File

@ -84,11 +84,11 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) {
break; break;
case Type::FunctionNoProto: case Type::FunctionNoProto:
D.RegisterPtr(PtrID,FunctionTypeNoProto::CreateImpl(Context,D)); D.RegisterPtr(PtrID,FunctionNoProtoType::CreateImpl(Context,D));
break; break;
case Type::FunctionProto: case Type::FunctionProto:
D.RegisterPtr(PtrID,FunctionTypeProto::CreateImpl(Context,D)); D.RegisterPtr(PtrID,FunctionProtoType::CreateImpl(Context,D));
break; break;
case Type::IncompleteArray: case Type::IncompleteArray:
@ -111,19 +111,22 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) {
D.RegisterPtr(PtrID, ReferenceType::CreateImpl(Context, D)); D.RegisterPtr(PtrID, ReferenceType::CreateImpl(Context, D));
break; break;
case Type::Tagged: case Type::Record:
D.RegisterPtr(PtrID, TagType::CreateImpl(Context, D)); case Type::CXXRecord:
case Type::Enum:
// FIXME: Implement this!
assert(false && "Can't deserialize tag types!");
break; break;
case Type::TypeName: case Type::Typedef:
D.RegisterPtr(PtrID, TypedefType::CreateImpl(Context, D)); D.RegisterPtr(PtrID, TypedefType::CreateImpl(Context, D));
break; break;
case Type::TypeOfExp: case Type::TypeOfExpr:
D.RegisterPtr(PtrID, TypeOfExpr::CreateImpl(Context, D)); D.RegisterPtr(PtrID, TypeOfExprType::CreateImpl(Context, D));
break; break;
case Type::TypeOfTyp: case Type::TypeOf:
D.RegisterPtr(PtrID, TypeOfType::CreateImpl(Context, D)); D.RegisterPtr(PtrID, TypeOfType::CreateImpl(Context, D));
break; break;
@ -199,22 +202,22 @@ Type* ConstantArrayType::CreateImpl(ASTContext& Context, Deserializer& D) {
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// FunctionTypeNoProto // FunctionNoProtoType
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void FunctionTypeNoProto::EmitImpl(Serializer& S) const { void FunctionNoProtoType::EmitImpl(Serializer& S) const {
S.Emit(getResultType()); S.Emit(getResultType());
} }
Type* FunctionTypeNoProto::CreateImpl(ASTContext& Context, Deserializer& D) { Type* FunctionNoProtoType::CreateImpl(ASTContext& Context, Deserializer& D) {
return Context.getFunctionTypeNoProto(QualType::ReadVal(D)).getTypePtr(); return Context.getFunctionNoProtoType(QualType::ReadVal(D)).getTypePtr();
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// FunctionTypeProto // FunctionProtoType
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void FunctionTypeProto::EmitImpl(Serializer& S) const { void FunctionProtoType::EmitImpl(Serializer& S) const {
S.Emit(getResultType()); S.Emit(getResultType());
S.EmitBool(isVariadic()); S.EmitBool(isVariadic());
S.EmitInt(getTypeQuals()); S.EmitInt(getTypeQuals());
@ -224,7 +227,7 @@ void FunctionTypeProto::EmitImpl(Serializer& S) const {
S.Emit(*I); S.Emit(*I);
} }
Type* FunctionTypeProto::CreateImpl(ASTContext& Context, Deserializer& D) { Type* FunctionProtoType::CreateImpl(ASTContext& Context, Deserializer& D) {
QualType ResultType = QualType::ReadVal(D); QualType ResultType = QualType::ReadVal(D);
bool isVariadic = D.ReadBool(); bool isVariadic = D.ReadBool();
unsigned TypeQuals = D.ReadInt(); unsigned TypeQuals = D.ReadInt();
@ -290,7 +293,9 @@ Type* TagType::CreateImpl(ASTContext& Context, Deserializer& D) {
std::vector<Type*>& Types = std::vector<Type*>& Types =
const_cast<std::vector<Type*>&>(Context.getTypes()); const_cast<std::vector<Type*>&>(Context.getTypes());
TagType* T = new TagType(NULL,QualType()); // FIXME: This is wrong: we need the subclasses to do the
// (de-)serialization.
TagType* T = new TagType(Record, NULL,QualType());
Types.push_back(T); Types.push_back(T);
// Deserialize the decl. // Deserialize the decl.
@ -313,7 +318,7 @@ Type* TypedefType::CreateImpl(ASTContext& Context, Deserializer& D) {
std::vector<Type*>& Types = std::vector<Type*>& Types =
const_cast<std::vector<Type*>&>(Context.getTypes()); const_cast<std::vector<Type*>&>(Context.getTypes());
TypedefType* T = new TypedefType(Type::TypeName, NULL, QualType::ReadVal(D)); TypedefType* T = new TypedefType(Type::Typedef, NULL, QualType::ReadVal(D));
Types.push_back(T); Types.push_back(T);
D.ReadPtr(T->Decl); // May be backpatched. D.ReadPtr(T->Decl); // May be backpatched.
@ -321,20 +326,21 @@ Type* TypedefType::CreateImpl(ASTContext& Context, Deserializer& D) {
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// TypeOfExpr // TypeOfExprType
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
void TypeOfExpr::EmitImpl(llvm::Serializer& S) const { void TypeOfExprType::EmitImpl(llvm::Serializer& S) const {
S.EmitOwnedPtr(TOExpr); S.EmitOwnedPtr(TOExpr);
} }
Type* TypeOfExpr::CreateImpl(ASTContext& Context, Deserializer& D) { Type* TypeOfExprType::CreateImpl(ASTContext& Context, Deserializer& D) {
Expr* E = D.ReadOwnedPtr<Expr>(Context); Expr* E = D.ReadOwnedPtr<Expr>(Context);
std::vector<Type*>& Types = std::vector<Type*>& Types =
const_cast<std::vector<Type*>&>(Context.getTypes()); const_cast<std::vector<Type*>&>(Context.getTypes());
TypeOfExpr* T = new TypeOfExpr(E, Context.getCanonicalType(E->getType())); TypeOfExprType* T
= new TypeOfExprType(E, Context.getCanonicalType(E->getType()));
Types.push_back(T); Types.push_back(T);
return T; return T;

View File

@ -956,7 +956,7 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
// Sanity check that this is *really* a unary function. This can // Sanity check that this is *really* a unary function. This can
// happen if people do weird things. // happen if people do weird things.
const FunctionTypeProto* FTP = dyn_cast<FunctionTypeProto>(FT); const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
if (!FTP || FTP->getNumArgs() != 1) if (!FTP || FTP->getNumArgs() != 1)
return getPersistentStopSummary(); return getPersistentStopSummary();

View File

@ -1127,10 +1127,10 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
NodeSet& Dst) NodeSet& Dst)
{ {
// Determine the type of function we're calling (if available). // Determine the type of function we're calling (if available).
const FunctionTypeProto *Proto = NULL; const FunctionProtoType *Proto = NULL;
QualType FnType = CE->getCallee()->IgnoreParens()->getType(); QualType FnType = CE->getCallee()->IgnoreParens()->getType();
if (const PointerType *FnTypePtr = FnType->getAsPointerType()) if (const PointerType *FnTypePtr = FnType->getAsPointerType())
Proto = FnTypePtr->getPointeeType()->getAsFunctionTypeProto(); Proto = FnTypePtr->getPointeeType()->getAsFunctionProtoType();
VisitCallRec(CE, Pred, AI, AE, Dst, Proto, /*ParamIdx=*/0); VisitCallRec(CE, Pred, AI, AE, Dst, Proto, /*ParamIdx=*/0);
} }
@ -1138,7 +1138,7 @@ void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred, void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
CallExpr::arg_iterator AI, CallExpr::arg_iterator AI,
CallExpr::arg_iterator AE, CallExpr::arg_iterator AE,
NodeSet& Dst, const FunctionTypeProto *Proto, NodeSet& Dst, const FunctionProtoType *Proto,
unsigned ParamIdx) { unsigned ParamIdx) {
// Process the arguments. // Process the arguments.

View File

@ -321,12 +321,12 @@ CodeGenModule::getGenericExtendedBlockLiteralType() {
/// function type for the block, including the first block literal argument. /// function type for the block, including the first block literal argument.
static QualType getBlockFunctionType(ASTContext &Ctx, static QualType getBlockFunctionType(ASTContext &Ctx,
const BlockPointerType *BPT) { const BlockPointerType *BPT) {
const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType()); const FunctionProtoType *FTy = cast<FunctionProtoType>(BPT->getPointeeType());
llvm::SmallVector<QualType, 8> Types; llvm::SmallVector<QualType, 8> Types;
Types.push_back(Ctx.getPointerType(Ctx.VoidTy)); Types.push_back(Ctx.getPointerType(Ctx.VoidTy));
for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(), for (FunctionProtoType::arg_type_iterator i = FTy->arg_type_begin(),
e = FTy->arg_type_end(); i != e; ++i) e = FTy->arg_type_end(); i != e; ++i)
Types.push_back(*i); Types.push_back(*i);
@ -455,9 +455,9 @@ llvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr,
const BlockInfo& Info, const BlockInfo& Info,
uint64_t &Size, uint64_t &Size,
uint64_t &Align, uint64_t &Align,
llvm::SmallVector<ValueDecl *, 8> &subBlockDeclRefDecls) { llvm::SmallVector<ValueDecl *, 8> &subBlockDeclRefDecls) {
const FunctionTypeProto *FTy = const FunctionProtoType *FTy =
cast<FunctionTypeProto>(Expr->getFunctionType()); cast<FunctionProtoType>(Expr->getFunctionType());
FunctionArgList Args; FunctionArgList Args;

View File

@ -37,13 +37,13 @@ using namespace CodeGen;
// FIXME: Use iterator and sidestep silly type array creation. // FIXME: Use iterator and sidestep silly type array creation.
const const
CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeNoProto *FTNP) { CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) {
return getFunctionInfo(FTNP->getResultType(), return getFunctionInfo(FTNP->getResultType(),
llvm::SmallVector<QualType, 16>()); llvm::SmallVector<QualType, 16>());
} }
const const
CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeProto *FTP) { CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) {
llvm::SmallVector<QualType, 16> ArgTys; llvm::SmallVector<QualType, 16> ArgTys;
// FIXME: Kill copy. // FIXME: Kill copy.
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
@ -53,9 +53,9 @@ CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeProto *FTP) {
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) {
const FunctionType *FTy = FD->getType()->getAsFunctionType(); const FunctionType *FTy = FD->getType()->getAsFunctionType();
if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(FTy)) if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FTy))
return getFunctionInfo(FTP); return getFunctionInfo(FTP);
return getFunctionInfo(cast<FunctionTypeNoProto>(FTy)); return getFunctionInfo(cast<FunctionNoProtoType>(FTy));
} }
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) {

View File

@ -179,7 +179,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
// Set up remainder of arguments if there is a prototype. // Set up remainder of arguments if there is a prototype.
// FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'! // FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'!
if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(Ty)) { if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit)); EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
} else { } else {
@ -481,6 +481,13 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
// Work out details of type. // Work out details of type.
switch (Ty->getTypeClass()) { switch (Ty->getTypeClass()) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
#define NON_CANONICAL_TYPE(Class, Base)
#define DEPENDENT_TYPE(Class, Base) case Type::Class:
#include "clang/AST/TypeNodes.def"
assert(false && "Dependent types cannot show up in debug information");
case Type::Complex: case Type::Complex:
case Type::Reference: case Type::Reference:
case Type::Vector: case Type::Vector:
@ -489,13 +496,16 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
case Type::ObjCInterface: case Type::ObjCInterface:
case Type::ObjCQualifiedInterface: case Type::ObjCQualifiedInterface:
case Type::ObjCQualifiedId: case Type::ObjCQualifiedId:
default:
return llvm::DIType(); return llvm::DIType();
case Type::Builtin: Slot = CreateType(cast<BuiltinType>(Ty), Unit); break; case Type::Builtin: Slot = CreateType(cast<BuiltinType>(Ty), Unit); break;
case Type::Pointer: Slot = CreateType(cast<PointerType>(Ty), Unit); break; case Type::Pointer: Slot = CreateType(cast<PointerType>(Ty), Unit); break;
case Type::TypeName: Slot = CreateType(cast<TypedefType>(Ty), Unit); break; case Type::Typedef: Slot = CreateType(cast<TypedefType>(Ty), Unit); break;
case Type::Tagged: Slot = CreateType(cast<TagType>(Ty), Unit); break; case Type::Record:
case Type::CXXRecord:
case Type::Enum:
Slot = CreateType(cast<TagType>(Ty), Unit);
break;
case Type::FunctionProto: case Type::FunctionProto:
case Type::FunctionNoProto: case Type::FunctionNoProto:
return Slot = CreateType(cast<FunctionType>(Ty), Unit); return Slot = CreateType(cast<FunctionType>(Ty), Unit);
@ -504,10 +514,10 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
case Type::VariableArray: case Type::VariableArray:
case Type::IncompleteArray: case Type::IncompleteArray:
return Slot = CreateType(cast<ArrayType>(Ty), Unit); return Slot = CreateType(cast<ArrayType>(Ty), Unit);
case Type::TypeOfExp: case Type::TypeOfExpr:
return Slot = getOrCreateType(cast<TypeOfExpr>(Ty)->getUnderlyingExpr() return Slot = getOrCreateType(cast<TypeOfExprType>(Ty)->getUnderlyingExpr()
->getType(), Unit); ->getType(), Unit);
case Type::TypeOfTyp: case Type::TypeOf:
return Slot = getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(), return Slot = getOrCreateType(cast<TypeOfType>(Ty)->getUnderlyingType(),
Unit); Unit);
} }

View File

@ -209,7 +209,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
FunctionArgList Args; FunctionArgList Args;
if (FD->getNumParams()) { if (FD->getNumParams()) {
const FunctionTypeProto* FProto = FD->getType()->getAsFunctionTypeProto(); const FunctionProtoType* FProto = FD->getType()->getAsFunctionProtoType();
assert(FProto && "Function def must have prototype!"); assert(FProto && "Function def must have prototype!");
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)

View File

@ -41,7 +41,7 @@ namespace clang {
class Decl; class Decl;
class EnumConstantDecl; class EnumConstantDecl;
class FunctionDecl; class FunctionDecl;
class FunctionTypeProto; class FunctionProtoType;
class LabelStmt; class LabelStmt;
class ObjCContainerDecl; class ObjCContainerDecl;
class ObjCInterfaceDecl; class ObjCInterfaceDecl;

View File

@ -174,13 +174,14 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
const clang::Type &Ty = *Context.getCanonicalType(T); const clang::Type &Ty = *Context.getCanonicalType(T);
switch (Ty.getTypeClass()) { switch (Ty.getTypeClass()) {
case Type::TypeName: // typedef isn't canonical. #define TYPE(Class, Base)
case Type::TemplateTypeParm:// template type parameters never generated #define ABSTRACT_TYPE(Class, Base)
case Type::ClassTemplateSpecialization: // these types are always sugar #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
case Type::DependentSizedArray: // dependent types are never generated #define DEPENDENT_TYPE(Class, Base) case Type::Class:
case Type::TypeOfExp: // typeof isn't canonical. #include "clang/AST/TypeNodes.def"
case Type::TypeOfTyp: // typeof isn't canonical. assert(false && "Non-canonical or dependent types aren't possible.");
assert(0 && "Non-canonical type, shouldn't happen"); break;
case Type::Builtin: { case Type::Builtin: {
switch (cast<BuiltinType>(Ty).getKind()) { switch (cast<BuiltinType>(Ty).getKind()) {
default: assert(0 && "Unknown builtin type!"); default: assert(0 && "Unknown builtin type!");
@ -265,10 +266,10 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
VT.getNumElements()); VT.getNumElements());
} }
case Type::FunctionNoProto: case Type::FunctionNoProto:
return GetFunctionType(getFunctionInfo(cast<FunctionTypeNoProto>(&Ty)), return GetFunctionType(getFunctionInfo(cast<FunctionNoProtoType>(&Ty)),
true); true);
case Type::FunctionProto: { case Type::FunctionProto: {
const FunctionTypeProto *FTP = cast<FunctionTypeProto>(&Ty); const FunctionProtoType *FTP = cast<FunctionProtoType>(&Ty);
return GetFunctionType(getFunctionInfo(FTP), FTP->isVariadic()); return GetFunctionType(getFunctionInfo(FTP), FTP->isVariadic());
} }
@ -300,7 +301,9 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
// Protocols don't influence the LLVM type. // Protocols don't influence the LLVM type.
return ConvertTypeRecursive(Context.getObjCIdType()); return ConvertTypeRecursive(Context.getObjCIdType());
case Type::Tagged: { case Type::Record:
case Type::CXXRecord:
case Type::Enum: {
const TagDecl *TD = cast<TagType>(Ty).getDecl(); const TagDecl *TD = cast<TagType>(Ty).getDecl();
const llvm::Type *Res = ConvertTagDeclType(TD); const llvm::Type *Res = ConvertTagDeclType(TD);

View File

@ -33,7 +33,7 @@ namespace clang {
class ABIInfo; class ABIInfo;
class ASTContext; class ASTContext;
class FieldDecl; class FieldDecl;
class FunctionTypeProto; class FunctionProtoType;
class ObjCInterfaceDecl; class ObjCInterfaceDecl;
class ObjCIvarDecl; class ObjCIvarDecl;
class PointerType; class PointerType;
@ -166,8 +166,8 @@ public:
const llvm::SmallVector<QualType,16> const llvm::SmallVector<QualType,16>
&ArgTys); &ArgTys);
const CGFunctionInfo &getFunctionInfo(const FunctionTypeNoProto *FTNP); const CGFunctionInfo &getFunctionInfo(const FunctionNoProtoType *FTNP);
const CGFunctionInfo &getFunctionInfo(const FunctionTypeProto *FTP); const CGFunctionInfo &getFunctionInfo(const FunctionProtoType *FTP);
const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD); const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD);
const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD); const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD);
const CGFunctionInfo &getFunctionInfo(QualType ResTy, const CGFunctionInfo &getFunctionInfo(QualType ResTy,

View File

@ -454,10 +454,10 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
if (MangleReturnType) if (MangleReturnType)
mangleType(T->getResultType()); mangleType(T->getResultType());
const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(T); const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
assert(Proto && "Can't mangle K&R function prototypes"); assert(Proto && "Can't mangle K&R function prototypes");
for (FunctionTypeProto::arg_type_iterator Arg = Proto->arg_type_begin(), for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
ArgEnd = Proto->arg_type_end(); ArgEnd = Proto->arg_type_end();
Arg != ArgEnd; ++Arg) Arg != ArgEnd; ++Arg)
mangleType(*Arg); mangleType(*Arg);

View File

@ -458,7 +458,7 @@ public:
Expr *From, QualType ToType, Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet); OverloadCandidateSet& CandidateSet);
void AddSurrogateCandidate(CXXConversionDecl *Conversion, void AddSurrogateCandidate(CXXConversionDecl *Conversion,
const FunctionTypeProto *Proto, const FunctionProtoType *Proto,
Expr *Object, Expr **Args, unsigned NumArgs, Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet); OverloadCandidateSet& CandidateSet);
bool AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S, bool AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
@ -1107,7 +1107,7 @@ public:
IdentifierInfo &Member); IdentifierInfo &Member);
bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
FunctionDecl *FDecl, FunctionDecl *FDecl,
const FunctionTypeProto *Proto, const FunctionProtoType *Proto,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc); SourceLocation RParenLoc);

View File

@ -144,8 +144,8 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) { if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
if (Format->getType() == "printf") { if (Format->getType() == "printf") {
bool HasVAListArg = false; bool HasVAListArg = false;
if (const FunctionTypeProto *Proto if (const FunctionProtoType *Proto
= FDecl->getType()->getAsFunctionTypeProto()) = FDecl->getType()->getAsFunctionProtoType())
HasVAListArg = !Proto->isVariadic(); HasVAListArg = !Proto->isVariadic();
CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1, CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
Format->getFirstArg() - 1); Format->getFirstArg() - 1);
@ -210,8 +210,8 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) {
// Determine whether the current function is variadic or not. // Determine whether the current function is variadic or not.
bool isVariadic; bool isVariadic;
if (getCurFunctionDecl()) { if (getCurFunctionDecl()) {
if (FunctionTypeProto* FTP = if (FunctionProtoType* FTP =
dyn_cast<FunctionTypeProto>(getCurFunctionDecl()->getType())) dyn_cast<FunctionProtoType>(getCurFunctionDecl()->getType()))
isVariadic = FTP->isVariadic(); isVariadic = FTP->isVariadic();
else else
isVariadic = false; isVariadic = false;

View File

@ -340,7 +340,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
// Create Decl objects for each parameter, adding them to the // Create Decl objects for each parameter, adding them to the
// FunctionDecl. // FunctionDecl.
if (FunctionTypeProto *FT = dyn_cast<FunctionTypeProto>(R)) { if (FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) {
llvm::SmallVector<ParmVarDecl*, 16> Params; llvm::SmallVector<ParmVarDecl*, 16> Params;
for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0, Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
@ -609,9 +609,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
if (!getLangOptions().CPlusPlus && if (!getLangOptions().CPlusPlus &&
Context.typesAreCompatible(OldQType, NewQType)) { Context.typesAreCompatible(OldQType, NewQType)) {
const FunctionType *NewFuncType = NewQType->getAsFunctionType(); const FunctionType *NewFuncType = NewQType->getAsFunctionType();
const FunctionTypeProto *OldProto = 0; const FunctionProtoType *OldProto = 0;
if (isa<FunctionTypeNoProto>(NewFuncType) && if (isa<FunctionNoProtoType>(NewFuncType) &&
(OldProto = OldQType->getAsFunctionTypeProto())) { (OldProto = OldQType->getAsFunctionProtoType())) {
// The old declaration provided a function prototype, but the // The old declaration provided a function prototype, but the
// new declaration does not. Merge in the prototype. // new declaration does not. Merge in the prototype.
llvm::SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(), llvm::SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(),
@ -625,7 +625,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
// Synthesize a parameter for each argument type. // Synthesize a parameter for each argument type.
llvm::SmallVector<ParmVarDecl*, 16> Params; llvm::SmallVector<ParmVarDecl*, 16> Params;
for (FunctionTypeProto::arg_type_iterator for (FunctionProtoType::arg_type_iterator
ParamType = OldProto->arg_type_begin(), ParamType = OldProto->arg_type_begin(),
ParamEnd = OldProto->arg_type_end(); ParamEnd = OldProto->arg_type_end();
ParamType != ParamEnd; ++ParamType) { ParamType != ParamEnd; ++ParamType) {
@ -1834,7 +1834,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// typedef void fn(int); // typedef void fn(int);
// fn f; // fn f;
// @endcode // @endcode
const FunctionTypeProto *FT = R->getAsFunctionTypeProto(); const FunctionProtoType *FT = R->getAsFunctionProtoType();
if (!FT) { if (!FT) {
// This is a typedef of a function with no prototype, so we // This is a typedef of a function with no prototype, so we
// don't need to do anything. // don't need to do anything.
@ -1845,7 +1845,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
} else { } else {
// Synthesize a parameter for each argument type. // Synthesize a parameter for each argument type.
llvm::SmallVector<ParmVarDecl*, 16> Params; llvm::SmallVector<ParmVarDecl*, 16> Params;
for (FunctionTypeProto::arg_type_iterator ArgType = FT->arg_type_begin(); for (FunctionProtoType::arg_type_iterator ArgType = FT->arg_type_begin();
ArgType != FT->arg_type_end(); ++ArgType) { ArgType != FT->arg_type_end(); ++ArgType) {
ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, ParmVarDecl *Param = ParmVarDecl::Create(Context, DC,
SourceLocation(), 0, SourceLocation(), 0,
@ -1900,7 +1900,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Functions marked "overloadable" must have a prototype (that // Functions marked "overloadable" must have a prototype (that
// we can't get through declaration merging). // we can't get through declaration merging).
if (!R->getAsFunctionTypeProto()) { if (!R->getAsFunctionProtoType()) {
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype) Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype)
<< NewFD; << NewFD;
InvalidDecl = true; InvalidDecl = true;

View File

@ -56,7 +56,7 @@ static bool isFunctionOrMethod(Decl *d) {
/// isFunctionOrMethod. /// isFunctionOrMethod.
static bool hasFunctionProto(Decl *d) { static bool hasFunctionProto(Decl *d) {
if (const FunctionType *FnTy = getFunctionType(d)) { if (const FunctionType *FnTy = getFunctionType(d)) {
return isa<FunctionTypeProto>(FnTy); return isa<FunctionProtoType>(FnTy);
} else { } else {
assert(isa<ObjCMethodDecl>(d)); assert(isa<ObjCMethodDecl>(d));
return true; return true;
@ -68,20 +68,20 @@ static bool hasFunctionProto(Decl *d) {
/// hasFunctionProto first). /// hasFunctionProto first).
static unsigned getFunctionOrMethodNumArgs(Decl *d) { static unsigned getFunctionOrMethodNumArgs(Decl *d) {
if (const FunctionType *FnTy = getFunctionType(d)) if (const FunctionType *FnTy = getFunctionType(d))
return cast<FunctionTypeProto>(FnTy)->getNumArgs(); return cast<FunctionProtoType>(FnTy)->getNumArgs();
return cast<ObjCMethodDecl>(d)->param_size(); return cast<ObjCMethodDecl>(d)->param_size();
} }
static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) { static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
if (const FunctionType *FnTy = getFunctionType(d)) if (const FunctionType *FnTy = getFunctionType(d))
return cast<FunctionTypeProto>(FnTy)->getArgType(Idx); return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType(); return cast<ObjCMethodDecl>(d)->param_begin()[Idx]->getType();
} }
static bool isFunctionOrMethodVariadic(Decl *d) { static bool isFunctionOrMethodVariadic(Decl *d) {
if (const FunctionType *FnTy = getFunctionType(d)) { if (const FunctionType *FnTy = getFunctionType(d)) {
const FunctionTypeProto *proto = cast<FunctionTypeProto>(FnTy); const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
return proto->isVariadic(); return proto->isVariadic();
} else { } else {
return cast<ObjCMethodDecl>(d)->isVariadic(); return cast<ObjCMethodDecl>(d)->isVariadic();
@ -688,7 +688,7 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
QualType FT = FD->getType(); QualType FT = FD->getType();
if (!FT->getAsFunctionTypeProto()->isVariadic()) { if (!FT->getAsFunctionProtoType()->isVariadic()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic); S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
return; return;
} }

View File

@ -1077,7 +1077,7 @@ bool Sema::CheckConstructorDeclarator(Declarator &D, QualType &R,
<< SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()) << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
<< SourceRange(D.getIdentifierLoc()); << SourceRange(D.getIdentifierLoc());
} }
if (R->getAsFunctionTypeProto()->getTypeQuals() != 0) { if (R->getAsFunctionProtoType()->getTypeQuals() != 0) {
DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun; DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
if (FTI.TypeQuals & QualType::Const) if (FTI.TypeQuals & QualType::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
@ -1095,7 +1095,7 @@ bool Sema::CheckConstructorDeclarator(Declarator &D, QualType &R,
// return type, since constructors don't have return types. We // return type, since constructors don't have return types. We
// *always* have to do this, because GetTypeForDeclarator will // *always* have to do this, because GetTypeForDeclarator will
// put in a result type of "int" when none was specified. // put in a result type of "int" when none was specified.
const FunctionTypeProto *Proto = R->getAsFunctionTypeProto(); const FunctionProtoType *Proto = R->getAsFunctionProtoType();
R = Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(), R = Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
Proto->getNumArgs(), Proto->getNumArgs(),
Proto->isVariadic(), Proto->isVariadic(),
@ -1187,7 +1187,7 @@ bool Sema::CheckDestructorDeclarator(Declarator &D, QualType &R,
<< SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()) << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
<< SourceRange(D.getIdentifierLoc()); << SourceRange(D.getIdentifierLoc());
} }
if (R->getAsFunctionTypeProto()->getTypeQuals() != 0) { if (R->getAsFunctionProtoType()->getTypeQuals() != 0) {
DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun; DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
if (FTI.TypeQuals & QualType::Const) if (FTI.TypeQuals & QualType::Const)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor) Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_destructor)
@ -1201,7 +1201,7 @@ bool Sema::CheckDestructorDeclarator(Declarator &D, QualType &R,
} }
// Make sure we don't have any parameters. // Make sure we don't have any parameters.
if (R->getAsFunctionTypeProto()->getNumArgs() > 0) { if (R->getAsFunctionProtoType()->getNumArgs() > 0) {
Diag(D.getIdentifierLoc(), diag::err_destructor_with_params); Diag(D.getIdentifierLoc(), diag::err_destructor_with_params);
// Delete the parameters. // Delete the parameters.
@ -1209,7 +1209,7 @@ bool Sema::CheckDestructorDeclarator(Declarator &D, QualType &R,
} }
// Make sure the destructor isn't variadic. // Make sure the destructor isn't variadic.
if (R->getAsFunctionTypeProto()->isVariadic()) if (R->getAsFunctionProtoType()->isVariadic())
Diag(D.getIdentifierLoc(), diag::err_destructor_variadic); Diag(D.getIdentifierLoc(), diag::err_destructor_variadic);
// Rebuild the function type "R" without any type qualifiers or // Rebuild the function type "R" without any type qualifiers or
@ -1258,7 +1258,7 @@ bool Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
} }
// Make sure we don't have any parameters. // Make sure we don't have any parameters.
if (R->getAsFunctionTypeProto()->getNumArgs() > 0) { if (R->getAsFunctionProtoType()->getNumArgs() > 0) {
Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params); Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params);
// Delete the parameters. // Delete the parameters.
@ -1266,7 +1266,7 @@ bool Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
} }
// Make sure the conversion function isn't variadic. // Make sure the conversion function isn't variadic.
if (R->getAsFunctionTypeProto()->isVariadic()) if (R->getAsFunctionProtoType()->isVariadic())
Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic); Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic);
// C++ [class.conv.fct]p4: // C++ [class.conv.fct]p4:
@ -1285,7 +1285,7 @@ bool Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
// of the errors above fired) and with the conversion type as the // of the errors above fired) and with the conversion type as the
// return type. // return type.
R = Context.getFunctionType(ConvType, 0, 0, false, R = Context.getFunctionType(ConvType, 0, 0, false,
R->getAsFunctionTypeProto()->getTypeQuals()); R->getAsFunctionProtoType()->getTypeQuals());
// C++0x explicit conversion operators. // C++0x explicit conversion operators.
if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x) if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
@ -2122,7 +2122,7 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {
// Overloaded operators other than operator() cannot be variadic. // Overloaded operators other than operator() cannot be variadic.
if (Op != OO_Call && if (Op != OO_Call &&
FnDecl->getType()->getAsFunctionTypeProto()->isVariadic()) { FnDecl->getType()->getAsFunctionProtoType()->isVariadic()) {
return Diag(FnDecl->getLocation(), diag::err_operator_overload_variadic) return Diag(FnDecl->getLocation(), diag::err_operator_overload_variadic)
<< FnDecl->getDeclName(); << FnDecl->getDeclName();
} }

View File

@ -887,8 +887,8 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// type. // type.
QualType T = Func->getType(); QualType T = Func->getType();
QualType NoProtoType = T; QualType NoProtoType = T;
if (const FunctionTypeProto *Proto = T->getAsFunctionTypeProto()) if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
NoProtoType = Context.getFunctionTypeNoProto(Proto->getResultType()); NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
return Owned(BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS)); return Owned(BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS));
} }
} }
@ -1949,7 +1949,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
bool bool
Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
FunctionDecl *FDecl, FunctionDecl *FDecl,
const FunctionTypeProto *Proto, const FunctionProtoType *Proto,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc) { SourceLocation RParenLoc) {
// C99 6.5.2.2p7 - the arguments are implicitly converted, as if by // C99 6.5.2.2p7 - the arguments are implicitly converted, as if by
@ -2164,12 +2164,12 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
// We know the result type of the call, set it. // We know the result type of the call, set it.
TheCall->setType(FuncT->getResultType().getNonReferenceType()); TheCall->setType(FuncT->getResultType().getNonReferenceType());
if (const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(FuncT)) { if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) {
if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs, if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
RParenLoc)) RParenLoc))
return ExprError(); return ExprError();
} else { } else {
assert(isa<FunctionTypeNoProto>(FuncT) && "Unknown FunctionType!"); assert(isa<FunctionNoProtoType>(FuncT) && "Unknown FunctionType!");
// Promote the arguments (C99 6.5.2.2p6). // Promote the arguments (C99 6.5.2.2p6).
for (unsigned i = 0; i != NumArgs; i++) { for (unsigned i = 0; i != NumArgs; i++) {
@ -4501,7 +4501,7 @@ Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body,
QualType BlockTy; QualType BlockTy;
if (!BSI->hasPrototype) if (!BSI->hasPrototype)
BlockTy = Context.getFunctionTypeNoProto(RetTy); BlockTy = Context.getFunctionNoProtoType(RetTy);
else else
BlockTy = Context.getFunctionType(RetTy, &ArgTypes[0], ArgTypes.size(), BlockTy = Context.getFunctionType(RetTy, &ArgTypes[0], ArgTypes.size(),
BSI->isVariadic, 0); BSI->isVariadic, 0);

View File

@ -1269,12 +1269,12 @@ addAssociatedClassesAndNamespaces(QualType T,
Context, Context,
AssociatedNamespaces, AssociatedClasses); AssociatedNamespaces, AssociatedClasses);
const FunctionTypeProto *Proto = dyn_cast<FunctionTypeProto>(FunctionType); const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FunctionType);
if (!Proto) if (!Proto)
return; return;
// Argument types // Argument types
for (FunctionTypeProto::arg_type_iterator Arg = Proto->arg_type_begin(), for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
ArgEnd = Proto->arg_type_end(); ArgEnd = Proto->arg_type_end();
Arg != ArgEnd; ++Arg) Arg != ArgEnd; ++Arg)
addAssociatedClassesAndNamespaces(*Arg, Context, addAssociatedClassesAndNamespaces(*Arg, Context,

View File

@ -310,12 +310,12 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
// If either of these functions is a K&R-style function (no // If either of these functions is a K&R-style function (no
// prototype), then we consider them to have matching signatures. // prototype), then we consider them to have matching signatures.
if (isa<FunctionTypeNoProto>(OldQType.getTypePtr()) || if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
isa<FunctionTypeNoProto>(NewQType.getTypePtr())) isa<FunctionNoProtoType>(NewQType.getTypePtr()))
return false; return false;
FunctionTypeProto* OldType = cast<FunctionTypeProto>(OldQType.getTypePtr()); FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType.getTypePtr());
FunctionTypeProto* NewType = cast<FunctionTypeProto>(NewQType.getTypePtr()); FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType.getTypePtr());
// The signature of a function includes the types of its // The signature of a function includes the types of its
// parameters (C++ 1.3.10), which includes the presence or absence // parameters (C++ 1.3.10), which includes the presence or absence
@ -1052,10 +1052,10 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
// differences in the argument and result types are in Objective-C // differences in the argument and result types are in Objective-C
// pointer conversions. If so, we permit the conversion (but // pointer conversions. If so, we permit the conversion (but
// complain about it). // complain about it).
const FunctionTypeProto *FromFunctionType const FunctionProtoType *FromFunctionType
= FromPointeeType->getAsFunctionTypeProto(); = FromPointeeType->getAsFunctionProtoType();
const FunctionTypeProto *ToFunctionType const FunctionProtoType *ToFunctionType
= ToPointeeType->getAsFunctionTypeProto(); = ToPointeeType->getAsFunctionProtoType();
if (FromFunctionType && ToFunctionType) { if (FromFunctionType && ToFunctionType) {
// If the function types are exactly the same, this isn't an // If the function types are exactly the same, this isn't an
// Objective-C pointer conversion. // Objective-C pointer conversion.
@ -1985,8 +1985,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions) bool SuppressUserConversions)
{ {
const FunctionTypeProto* Proto const FunctionProtoType* Proto
= dyn_cast<FunctionTypeProto>(Function->getType()->getAsFunctionType()); = dyn_cast<FunctionProtoType>(Function->getType()->getAsFunctionType());
assert(Proto && "Functions without a prototype cannot be overloaded"); assert(Proto && "Functions without a prototype cannot be overloaded");
assert(!isa<CXXConversionDecl>(Function) && assert(!isa<CXXConversionDecl>(Function) &&
"Use AddConversionCandidate for conversion functions"); "Use AddConversionCandidate for conversion functions");
@ -2075,8 +2075,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
OverloadCandidateSet& CandidateSet, OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions) bool SuppressUserConversions)
{ {
const FunctionTypeProto* Proto const FunctionProtoType* Proto
= dyn_cast<FunctionTypeProto>(Method->getType()->getAsFunctionType()); = dyn_cast<FunctionProtoType>(Method->getType()->getAsFunctionType());
assert(Proto && "Methods without a prototype cannot be overloaded"); assert(Proto && "Methods without a prototype cannot be overloaded");
assert(!isa<CXXConversionDecl>(Method) && assert(!isa<CXXConversionDecl>(Method) &&
"Use AddConversionCandidate for conversion functions"); "Use AddConversionCandidate for conversion functions");
@ -2228,7 +2228,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
/// with the given arguments (C++ [over.call.object]p2-4). Proto is /// with the given arguments (C++ [over.call.object]p2-4). Proto is
/// the type of function that we'll eventually be calling. /// the type of function that we'll eventually be calling.
void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
const FunctionTypeProto *Proto, const FunctionProtoType *Proto,
Expr *Object, Expr **Args, unsigned NumArgs, Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet) { OverloadCandidateSet& CandidateSet) {
CandidateSet.push_back(OverloadCandidate()); CandidateSet.push_back(OverloadCandidate());
@ -2318,7 +2318,7 @@ IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType())) if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType()))
return true; return true;
const FunctionTypeProto *Proto = Fn->getType()->getAsFunctionTypeProto(); const FunctionProtoType *Proto = Fn->getType()->getAsFunctionProtoType();
if (Proto->getNumArgs() < 1) if (Proto->getNumArgs() < 1)
return false; return false;
@ -3773,7 +3773,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
MemExpr->setBase(ObjectArg); MemExpr->setBase(ObjectArg);
// Convert the rest of the arguments // Convert the rest of the arguments
const FunctionTypeProto *Proto = cast<FunctionTypeProto>(Method->getType()); const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType());
if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs, if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
RParenLoc)) RParenLoc))
return true; return true;
@ -3842,7 +3842,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (const PointerType *ConvPtrType = ConvType->getAsPointerType()) if (const PointerType *ConvPtrType = ConvType->getAsPointerType())
ConvType = ConvPtrType->getPointeeType(); ConvType = ConvPtrType->getPointeeType();
if (const FunctionTypeProto *Proto = ConvType->getAsFunctionTypeProto()) if (const FunctionProtoType *Proto = ConvType->getAsFunctionProtoType())
AddSurrogateCandidate(Conv, Proto, Object, Args, NumArgs, CandidateSet); AddSurrogateCandidate(Conv, Proto, Object, Args, NumArgs, CandidateSet);
} }
@ -3909,7 +3909,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// that calls this method, using Object for the implicit object // that calls this method, using Object for the implicit object
// parameter and passing along the remaining arguments. // parameter and passing along the remaining arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function); CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
const FunctionTypeProto *Proto = Method->getType()->getAsFunctionTypeProto(); const FunctionProtoType *Proto = Method->getType()->getAsFunctionProtoType();
unsigned NumArgsInProto = Proto->getNumArgs(); unsigned NumArgsInProto = Proto->getNumArgs();
unsigned NumArgsToCheck = NumArgs; unsigned NumArgsToCheck = NumArgs;

View File

@ -172,7 +172,7 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
Expr *E = static_cast<Expr *>(DS.getTypeRep()); Expr *E = static_cast<Expr *>(DS.getTypeRep());
assert(E && "Didn't get an expression for typeof?"); assert(E && "Didn't get an expression for typeof?");
// TypeQuals handled by caller. // TypeQuals handled by caller.
Result = Context.getTypeOfExpr(E); Result = Context.getTypeOfExprType(E);
break; break;
} }
case DeclSpec::TST_error: case DeclSpec::TST_error:
@ -505,7 +505,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0); T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0);
} else { } else {
// Simple void foo(), where the incoming T is the result type. // Simple void foo(), where the incoming T is the result type.
T = Context.getFunctionTypeNoProto(T); T = Context.getFunctionNoProtoType(T);
} }
} else if (FTI.ArgInfo[0].Param == 0) { } else if (FTI.ArgInfo[0].Param == 0) {
// C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition. // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
@ -540,7 +540,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
// Look for 'void'. void is allowed only as a single argument to a // Look for 'void'. void is allowed only as a single argument to a
// function with no other parameters (C99 6.7.5.3p10). We record // function with no other parameters (C99 6.7.5.3p10). We record
// int(void) as a FunctionTypeProto with an empty argument list. // int(void) as a FunctionProtoType with an empty argument list.
else if (ArgTy->isVoidType()) { else if (ArgTy->isVoidType()) {
// If this is something like 'float(int, void)', reject it. 'void' // If this is something like 'float(int, void)', reject it. 'void'
// is an incomplete type (C99 6.2.5p19) and function decls cannot // is an incomplete type (C99 6.2.5p19) and function decls cannot
@ -634,8 +634,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
} }
if (getLangOptions().CPlusPlus && T->isFunctionType()) { if (getLangOptions().CPlusPlus && T->isFunctionType()) {
const FunctionTypeProto *FnTy = T->getAsFunctionTypeProto(); const FunctionProtoType *FnTy = T->getAsFunctionProtoType();
assert(FnTy && "Why oh why is there not a FunctionTypeProto here ?"); assert(FnTy && "Why oh why is there not a FunctionProtoType here ?");
// C++ 8.3.5p4: A cv-qualifier-seq shall only be part of the function type // C++ 8.3.5p4: A cv-qualifier-seq shall only be part of the function type
// for a nonstatic member function, the function type to which a pointer // for a nonstatic member function, the function type to which a pointer