]> granicus.if.org Git - clang/commitdiff
Delay checking for mutable const fields until we're checking the field.
authorJohn McCall <rjmccall@apple.com>
Fri, 4 Jun 2010 08:34:12 +0000 (08:34 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 4 Jun 2010 08:34:12 +0000 (08:34 +0000)
Allows this check to work properly for instantiated fields and removes
an unnecessary GetTypeForDeclarator call.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105463 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp

index af020990dda5c51d6366b8e53b6dcc749fd1b9df..02a157f1d8547dd17fee12083a541648472e1ec3 100644 (file)
@@ -5740,6 +5740,24 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
     ZeroWidth = false;
   }
 
+  // Check that 'mutable' is consistent with the type of the declaration.
+  if (!InvalidDecl && Mutable) {
+    unsigned DiagID = 0;
+    if (T->isReferenceType())
+      DiagID = diag::err_mutable_reference;
+    else if (T.isConstQualified())
+      DiagID = diag::err_mutable_const;
+
+    if (DiagID) {
+      SourceLocation ErrLoc = Loc;
+      if (D && D->getDeclSpec().getStorageClassSpecLoc().isValid())
+        ErrLoc = D->getDeclSpec().getStorageClassSpecLoc();
+      Diag(ErrLoc, DiagID);
+      Mutable = false;
+      InvalidDecl = true;
+    }
+  }
+
   FieldDecl *NewFD = FieldDecl::Create(Context, Record, Loc, II, T, TInfo,
                                        BitWidth, Mutable);
   if (InvalidDecl)
index 76a2f4f612fd539368fd890f7b2212a1f26bd8f2..db7f0bb79e790d61ea32327faed5cccb4f4d799b 100644 (file)
@@ -886,10 +886,18 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
   Expr *Init = static_cast<Expr*>(InitExpr);
   SourceLocation Loc = D.getIdentifierLoc();
 
-  bool isFunc = D.isFunctionDeclarator();
-
+  assert(isa<CXXRecordDecl>(CurContext));
   assert(!DS.isFriendSpecified());
 
+  bool isFunc = false;
+  if (D.isFunctionDeclarator())
+    isFunc = true;
+  else if (D.getNumTypeObjects() == 0 &&
+           D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename) {
+    QualType TDType = GetTypeFromParser(DS.getTypeRep());
+    isFunc = TDType->isFunctionType();
+  }
+
   // 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
@@ -911,22 +919,6 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
         // FIXME: It would be nicer if the keyword was ignored only for this
         // declarator. Otherwise we could get follow-up errors.
         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);
-          // FIXME: It would be nicer if the keyword was ignored only for this
-          // declarator. Otherwise we could get follow-up errors.
-          D.getMutableDeclSpec().ClearStorageClassSpecs();
-        }
       }
       break;
     default:
@@ -938,18 +930,6 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
       D.getMutableDeclSpec().ClearStorageClassSpecs();
   }
 
-  if (!isFunc &&
-      D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename &&
-      D.getNumTypeObjects() == 0) {
-    // Check also for this case:
-    //
-    // typedef int f();
-    // f a;
-    //
-    QualType TDType = GetTypeFromParser(DS.getTypeRep());
-    isFunc = TDType->isFunctionType();
-  }
-
   bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified ||
                        DS.getStorageClassSpec() == DeclSpec::SCS_mutable) &&
                       !isFunc);