summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2008-11-14 23:42:31 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2008-11-14 23:42:31 +0000
commitccdfabab351ae15ee2bb8cfd14ee2614761bbfde (patch)
tree7e969e6177f8024faf4e691ae9a2b95522edbc21 /clang/lib/Sema/SemaDeclCXX.cpp
parent494d410b3200552f6bd0da2554f05b1c7f7d321e (diff)
downloadbcm5719-llvm-ccdfabab351ae15ee2bb8cfd14ee2614761bbfde.tar.gz
bcm5719-llvm-ccdfabab351ae15ee2bb8cfd14ee2614761bbfde.zip
Implement parsing and semantic checking of the 'mutable' keyword.
Thanks to Doug for the review. Actual effects of mutable to follow. llvm-svn: 59331
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp34
1 files changed, 32 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 9bf10cece81..f8369b3d8da 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -425,14 +425,44 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
Expr *Init = static_cast<Expr*>(InitExpr);
SourceLocation Loc = D.getIdentifierLoc();
+ bool isFunc = D.isFunctionDeclarator();
+
// C++ 9.2p6: A member shall not be declared to have automatic storage
// duration (auto, register) or with the extern storage-class-specifier.
+ // C++ 7.1.1p8: The mutable specifier can be applied only to names of class
+ // data members and cannot be applied to names declared const or static,
+ // and cannot be applied to reference members.
switch (DS.getStorageClassSpec()) {
case DeclSpec::SCS_unspecified:
case DeclSpec::SCS_typedef:
case DeclSpec::SCS_static:
// FALL THROUGH.
break;
+ case DeclSpec::SCS_mutable:
+ if (isFunc) {
+ if (DS.getStorageClassSpecLoc().isValid())
+ Diag(DS.getStorageClassSpecLoc(),
+ diag::err_mutable_function);
+ else
+ Diag(DS.getThreadSpecLoc(),
+ diag::err_mutable_function);
+ D.getMutableDeclSpec().ClearStorageClassSpecs();
+ } else {
+ QualType T = GetTypeForDeclarator(D, S);
+ diag::kind err = static_cast<diag::kind>(0);
+ if (T->isReferenceType())
+ err = diag::err_mutable_reference;
+ else if (T.isConstQualified())
+ err = diag::err_mutable_const;
+ if (err != 0) {
+ if (DS.getStorageClassSpecLoc().isValid())
+ Diag(DS.getStorageClassSpecLoc(), err);
+ else
+ Diag(DS.getThreadSpecLoc(), err);
+ D.getMutableDeclSpec().ClearStorageClassSpecs();
+ }
+ }
+ break;
default:
if (DS.getStorageClassSpecLoc().isValid())
Diag(DS.getStorageClassSpecLoc(),
@@ -442,7 +472,6 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
D.getMutableDeclSpec().ClearStorageClassSpecs();
}
- bool isFunc = D.isFunctionDeclarator();
if (!isFunc &&
D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typedef &&
D.getNumTypeObjects() == 0) {
@@ -455,7 +484,8 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
isFunc = Context.getTypeDeclType(cast<TypeDecl>(TD))->isFunctionType();
}
- bool isInstField = (DS.getStorageClassSpec() == DeclSpec::SCS_unspecified &&
+ bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified ||
+ DS.getStorageClassSpec() == DeclSpec::SCS_mutable) &&
!isFunc);
Decl *Member;
OpenPOWER on IntegriCloud