-Add support for cv-qualifiers after function declarators.
-Add withConst/withVolatile/withRestrict methods to QualType class, that return the QualType plus the respective qualifier.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58120 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 4c36b09..c83c4de 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1820,7 +1820,7 @@
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/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9b1543f..6fd1c5c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -402,7 +402,9 @@
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/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index a12ec3a..7bcd1e5 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -409,7 +409,7 @@
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 @@
ArgTys.push_back(ArgTy);
}
T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
- FTI.isVariadic);
+ FTI.isVariadic, FTI.TypeQuals);
}
break;
}
@@ -491,6 +491,31 @@
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!)