diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index 821bf2d9c3e9..3e8216e6679f 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/Driver/RewriteObjC.cpp @@ -1750,7 +1750,7 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() { Context->CharTy.getQualifiedType(QualType::Const))); QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(), &ArgTys[0], ArgTys.size(), - false /*isVariadic*/); + false /*isVariadic*/, 0); SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SelGetUidIdent, getFuncType, @@ -1765,7 +1765,7 @@ void RewriteObjC::SynthGetProtocolFunctionDecl() { Context->CharTy.getQualifiedType(QualType::Const))); QualType getFuncType = Context->getFunctionType(Context->getObjCProtoType(), &ArgTys[0], ArgTys.size(), - false /*isVariadic*/); + false /*isVariadic*/, 0); GetProtocolFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SelGetProtoIdent, getFuncType, @@ -1793,7 +1793,7 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - false); + false, 0); SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, @@ -1812,7 +1812,7 @@ void RewriteObjC::SynthMsgSendFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/); + true /*isVariadic*/, 0); MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, @@ -1834,7 +1834,7 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/); + true /*isVariadic*/, 0); MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, @@ -1853,7 +1853,7 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/); + true /*isVariadic*/, 0); MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, @@ -1877,7 +1877,7 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - true /*isVariadic*/); + true /*isVariadic*/, 0); MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, @@ -1896,7 +1896,7 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() { ArgTys.push_back(argT); QualType msgSendType = Context->getFunctionType(Context->DoubleTy, &ArgTys[0], ArgTys.size(), - true /*isVariadic*/); + true /*isVariadic*/, 0); MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, @@ -1911,7 +1911,7 @@ void RewriteObjC::SynthGetClassFunctionDecl() { Context->CharTy.getQualifiedType(QualType::Const))); QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - false /*isVariadic*/); + false /*isVariadic*/, 0); GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), getClassIdent, getClassType, @@ -1926,7 +1926,7 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() { Context->CharTy.getQualifiedType(QualType::Const))); QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), - false /*isVariadic*/); + false /*isVariadic*/, 0); GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), getClassIdent, getClassType, @@ -2284,7 +2284,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { QualType castType = Context->getFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), // If we don't have a method decl, force a variadic cast. - Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true); + Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0); castType = Context->getPointerType(castType); cast = new ExplicitCastExpr(castType, cast, SourceLocation()); @@ -2310,7 +2310,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { // Now do the "normal" pointer to function cast. castType = Context->getFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), - Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false); + Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0); castType = Context->getPointerType(castType); cast = new ExplicitCastExpr(castType, cast, SourceLocation()); diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 99ff107d8daa..b30fbfa44413 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -209,7 +209,7 @@ public: /// list. isVariadic indicates whether the argument list includes '...'. QualType getFunctionType(QualType ResultTy, const QualType *ArgArray, unsigned NumArgs, bool isVariadic, - unsigned TypeQuals = 0); + unsigned TypeQuals); /// getTypeDeclType - Return the unique reference to the type for /// the specified type declaration. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f8129969b7b6..095414bde103 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -913,7 +913,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, Canonical = getFunctionType(getCanonicalType(ResultTy), &CanonicalArgs[0], NumArgs, - isVariadic); + isVariadic, TypeQuals); // Get the new insert position for the node we care about. FunctionTypeProto *NewIP = @@ -1947,6 +1947,9 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { if (lproto->isVariadic() != rproto->isVariadic()) return QualType(); + if (lproto->getTypeQuals() != rproto->getTypeQuals()) + return QualType(); + // Check argument compatibility llvm::SmallVector types; for (unsigned i = 0; i < lproto_nargs; i++) { @@ -1963,7 +1966,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { if (allLTypes) return lhs; if (allRTypes) return rhs; return getFunctionType(retType, types.begin(), types.size(), - lproto->isVariadic()); + lproto->isVariadic(), lproto->getTypeQuals()); } if (lproto) allRTypes = false; @@ -1988,7 +1991,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) { if (allLTypes) return lhs; if (allRTypes) return rhs; return getFunctionType(retType, proto->arg_type_begin(), - proto->getNumArgs(), lproto->isVariadic()); + proto->getNumArgs(), lproto->isVariadic(), + lproto->getTypeQuals()); } if (allLTypes) return lhs; diff --git a/clang/lib/AST/Builtins.cpp b/clang/lib/AST/Builtins.cpp index 1823ee605596..a721c6ea8c18 100644 --- a/clang/lib/AST/Builtins.cpp +++ b/clang/lib/AST/Builtins.cpp @@ -203,5 +203,5 @@ QualType Builtin::Context::GetBuiltinType(unsigned id, if (ArgTypes.size() == 0 && TypeStr[0] == '.') return Context.getFunctionTypeNoProto(ResType); return Context.getFunctionType(ResType, &ArgTypes[0], ArgTypes.size(), - TypeStr[0] == '.'); + TypeStr[0] == '.', 0); } diff --git a/clang/lib/AST/TypeSerialization.cpp b/clang/lib/AST/TypeSerialization.cpp index ff784ccc2792..b336722763eb 100644 --- a/clang/lib/AST/TypeSerialization.cpp +++ b/clang/lib/AST/TypeSerialization.cpp @@ -194,6 +194,7 @@ Type* FunctionTypeNoProto::CreateImpl(ASTContext& Context, Deserializer& D) { void FunctionTypeProto::EmitImpl(Serializer& S) const { S.Emit(getResultType()); S.EmitBool(isVariadic()); + S.EmitInt(getTypeQuals()); S.EmitInt(getNumArgs()); for (arg_type_iterator I=arg_type_begin(), E=arg_type_end(); I!=E; ++I) @@ -203,6 +204,7 @@ void FunctionTypeProto::EmitImpl(Serializer& S) const { Type* FunctionTypeProto::CreateImpl(ASTContext& Context, Deserializer& D) { QualType ResultType = QualType::ReadVal(D); bool isVariadic = D.ReadBool(); + unsigned TypeQuals = D.ReadInt(); unsigned NumArgs = D.ReadInt(); llvm::SmallVector Args; @@ -211,7 +213,7 @@ Type* FunctionTypeProto::CreateImpl(ASTContext& Context, Deserializer& D) { Args.push_back(QualType::ReadVal(D)); return Context.getFunctionType(ResultType,&*Args.begin(), - NumArgs,isVariadic).getTypePtr(); + NumArgs,isVariadic,TypeQuals).getTypePtr(); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6fd1c5cc2fdd..13b3959d8c35 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3033,7 +3033,7 @@ Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body, BlockTy = Context.getFunctionTypeNoProto(RetTy); else BlockTy = Context.getFunctionType(RetTy, &ArgTypes[0], ArgTypes.size(), - BSI->isVariadic); + BSI->isVariadic, 0); BlockTy = Context.getBlockPointerType(BlockTy); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7bcd1e5765fd..93f182c27e65 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -513,7 +513,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // Strip the cv-quals from the type. T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), - FnTy->getNumArgs(), FnTy->isVariadic()); + FnTy->getNumArgs(), FnTy->isVariadic(), 0); } } @@ -556,7 +556,7 @@ QualType Sema::ObjCGetTypeForMethodDefinition(DeclTy *D) { ArgTys.push_back(ArgTy); } T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(), - MDecl->isVariadic()); + MDecl->isVariadic(), 0); return T; }