diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-11-14 23:42:31 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-11-14 23:42:31 +0000 |
commit | ccdfabab351ae15ee2bb8cfd14ee2614761bbfde (patch) | |
tree | 7e969e6177f8024faf4e691ae9a2b95522edbc21 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 494d410b3200552f6bd0da2554f05b1c7f7d321e (diff) | |
download | bcm5719-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.cpp | 34 |
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; |