зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
7b6d25b04c
Коммит
4bde1e13d3
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче