Delay checking for mutable const fields until we're checking the field.

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
This commit is contained in:
John McCall 2010-06-04 08:34:12 +00:00
Родитель 7b6d25b04c
Коммит 4bde1e13d3
2 изменённых файлов: 28 добавлений и 30 удалений

Просмотреть файл

@ -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)

Просмотреть файл

@ -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);