From 22c40fa28551f0da487f399a2fe0d3d25edf3edc Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 24 Oct 2008 21:46:40 +0000 Subject: -Add support for cv-qualifiers after function declarators. -Add withConst/withVolatile/withRestrict methods to QualType class, that return the QualType plus the respective qualifier. llvm-svn: 58120 --- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 4 +++- clang/lib/Sema/SemaType.cpp | 29 +++++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) (limited to 'clang/lib/Sema') diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4c36b09af80..c83c4def467 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1820,7 +1820,7 @@ ScopedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, Error = Error; // Silence warning. assert(!Error && "Error setting up implicit decl!"); Declarator D(DS, Declarator::BlockContext); - D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, Loc)); + D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, 0, Loc)); D.SetIdentifier(&II, Loc); // Insert this function into translation-unit scope. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9b1543f7901..6fd1c5cc2fd 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -402,7 +402,9 @@ Sema::ExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc, if (FD->isInvalidDecl()) return true; - return new DeclRefExpr(FD, FD->getType(), Loc); + // FIXME: Handle 'mutable'. + return new DeclRefExpr(FD, + FD->getType().getWithAdditionalQualifiers(MD->getTypeQualifiers()),Loc); } return Diag(Loc, diag::err_invalid_non_static_member_use, FD->getName()); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index a12ec3ad7c8..7bcd1e5765f 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -409,7 +409,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { if (getLangOptions().CPlusPlus) { // C++ 8.3.5p2: If the parameter-declaration-clause is empty, the // function takes no arguments. - T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic); + T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic,FTI.TypeQuals); } else { // Simple void foo(), where the incoming T is the result type. T = Context.getFunctionTypeNoProto(T); @@ -482,7 +482,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { ArgTys.push_back(ArgTy); } T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(), - FTI.isVariadic); + FTI.isVariadic, FTI.TypeQuals); } break; } @@ -491,6 +491,31 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { if (const AttributeList *AL = DeclType.getAttrs()) ProcessTypeAttributeList(T, AL); } + + if (getLangOptions().CPlusPlus && T->isFunctionType()) { + const FunctionTypeProto *FnTy = T->getAsFunctionTypeProto(); + assert(FnTy && "Why oh why is there not a FunctionTypeProto here ?"); + + // 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 + // to member refers, or the top-level function type of a function typedef + // declaration. + if (FnTy->getTypeQuals() != 0 && + D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef && + (D.getContext() != Declarator::MemberContext || + D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)) { + + if (D.isFunctionDeclarator()) + Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_function_type); + else + Diag(D.getIdentifierLoc(), + diag::err_invalid_qualified_typedef_function_type_use); + + // Strip the cv-quals from the type. + T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), + FnTy->getNumArgs(), FnTy->isVariadic()); + } + } // If there were any type attributes applied to the decl itself (not the // type, apply the type attribute to the type!) -- cgit v1.2.3