forked from OSchip/llvm-project
Improve the warning for cv-qualifiers on free functions, from Ahmed Charles!
llvm-svn: 142478
This commit is contained in:
parent
5fdc4de718
commit
e248eea214
|
@ -1105,6 +1105,16 @@ struct DeclaratorChunk {
|
|||
/// If this is an invalid location, there is no ref-qualifier.
|
||||
unsigned RefQualifierLoc;
|
||||
|
||||
/// \brief The location of the const-qualifier, if any.
|
||||
///
|
||||
/// If this is an invalid location, there is no const-qualifier.
|
||||
unsigned ConstQualifierLoc;
|
||||
|
||||
/// \brief The location of the volatile-qualifier, if any.
|
||||
///
|
||||
/// If this is an invalid location, there is no volatile-qualifier.
|
||||
unsigned VolatileQualifierLoc;
|
||||
|
||||
/// \brief The location of the 'mutable' qualifer in a lambda-declarator, if
|
||||
/// any.
|
||||
unsigned MutableLoc;
|
||||
|
@ -1170,6 +1180,16 @@ struct DeclaratorChunk {
|
|||
return SourceLocation::getFromRawEncoding(RefQualifierLoc);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the ref-qualifier, if any.
|
||||
SourceLocation getConstQualifierLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(ConstQualifierLoc);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the ref-qualifier, if any.
|
||||
SourceLocation getVolatileQualifierLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(VolatileQualifierLoc);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the 'mutable' qualifier, if any.
|
||||
SourceLocation getMutableLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(MutableLoc);
|
||||
|
@ -1306,6 +1326,8 @@ struct DeclaratorChunk {
|
|||
unsigned TypeQuals,
|
||||
bool RefQualifierIsLvalueRef,
|
||||
SourceLocation RefQualifierLoc,
|
||||
SourceLocation ConstQualifierLoc,
|
||||
SourceLocation VolatileQualifierLoc,
|
||||
SourceLocation MutableLoc,
|
||||
ExceptionSpecificationType ESpecType,
|
||||
SourceLocation ESpecLoc,
|
||||
|
|
|
@ -4031,6 +4031,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
|
|||
DeclSpec DS(AttrFactory);
|
||||
bool RefQualifierIsLValueRef = true;
|
||||
SourceLocation RefQualifierLoc;
|
||||
SourceLocation ConstQualifierLoc;
|
||||
SourceLocation VolatileQualifierLoc;
|
||||
ExceptionSpecificationType ESpecType = EST_None;
|
||||
SourceRange ESpecRange;
|
||||
SmallVector<ParsedType, 2> DynamicExceptions;
|
||||
|
@ -4069,8 +4071,11 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
|
|||
|
||||
// Parse cv-qualifier-seq[opt].
|
||||
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
||||
if (!DS.getSourceRange().getEnd().isInvalid())
|
||||
if (!DS.getSourceRange().getEnd().isInvalid()) {
|
||||
EndLoc = DS.getSourceRange().getEnd();
|
||||
ConstQualifierLoc = DS.getConstSpecLoc();
|
||||
VolatileQualifierLoc = DS.getVolatileSpecLoc();
|
||||
}
|
||||
|
||||
// Parse ref-qualifier[opt].
|
||||
if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
|
||||
|
@ -4112,7 +4117,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
|
|||
ParamInfo.data(), ParamInfo.size(),
|
||||
DS.getTypeQualifiers(),
|
||||
RefQualifierIsLValueRef,
|
||||
RefQualifierLoc,
|
||||
RefQualifierLoc, ConstQualifierLoc,
|
||||
VolatileQualifierLoc,
|
||||
/*MutableLoc=*/SourceLocation(),
|
||||
ESpecType, ESpecRange.getBegin(),
|
||||
DynamicExceptions.data(),
|
||||
|
|
|
@ -2280,6 +2280,8 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
|||
0, 0, 0,
|
||||
true, SourceLocation(),
|
||||
SourceLocation(),
|
||||
SourceLocation(),
|
||||
SourceLocation(),
|
||||
EST_None,
|
||||
SourceLocation(),
|
||||
0, 0, 0, 0,
|
||||
|
|
|
@ -748,6 +748,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
|
|||
DS.getTypeQualifiers(),
|
||||
/*RefQualifierIsLValueRef=*/true,
|
||||
/*RefQualifierLoc=*/SourceLocation(),
|
||||
/*ConstQualifierLoc=*/SourceLocation(),
|
||||
/*VolatileQualifierLoc=*/SourceLocation(),
|
||||
MutableLoc,
|
||||
ESpecType, ESpecRange.getBegin(),
|
||||
DynamicExceptions.data(),
|
||||
|
|
|
@ -151,6 +151,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
|||
unsigned TypeQuals,
|
||||
bool RefQualifierIsLvalueRef,
|
||||
SourceLocation RefQualifierLoc,
|
||||
SourceLocation ConstQualifierLoc,
|
||||
SourceLocation
|
||||
VolatileQualifierLoc,
|
||||
SourceLocation MutableLoc,
|
||||
ExceptionSpecificationType
|
||||
ESpecType,
|
||||
|
@ -177,6 +180,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
|||
I.Fun.ArgInfo = 0;
|
||||
I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
|
||||
I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
|
||||
I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding();
|
||||
I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding();
|
||||
I.Fun.MutableLoc = MutableLoc.getRawEncoding();
|
||||
I.Fun.ExceptionSpecType = ESpecType;
|
||||
I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding();
|
||||
|
|
|
@ -7222,6 +7222,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
|||
Declarator D(DS, Declarator::BlockContext);
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
|
||||
0, 0, true, SourceLocation(),
|
||||
SourceLocation(), SourceLocation(),
|
||||
SourceLocation(),
|
||||
EST_None, SourceLocation(),
|
||||
0, 0, 0, 0, Loc, Loc, D),
|
||||
|
|
|
@ -555,6 +555,8 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
|
|||
/*args*/ 0, 0,
|
||||
/*type quals*/ 0,
|
||||
/*ref-qualifier*/true, SourceLocation(),
|
||||
/*const qualifier*/SourceLocation(),
|
||||
/*volatile qualifier*/SourceLocation(),
|
||||
/*mutable qualifier*/SourceLocation(),
|
||||
/*EH*/ EST_None, SourceLocation(), 0, 0, 0, 0,
|
||||
/*parens*/ loc, loc,
|
||||
|
@ -2431,10 +2433,37 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
<< Quals;
|
||||
} else {
|
||||
if (FnTy->getTypeQuals() != 0) {
|
||||
if (D.isFunctionDeclarator())
|
||||
S.Diag(D.getIdentifierLoc(),
|
||||
diag::err_invalid_qualified_function_type);
|
||||
else
|
||||
if (D.isFunctionDeclarator()) {
|
||||
SourceRange Range = D.getIdentifierLoc();
|
||||
for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
|
||||
const DeclaratorChunk &Chunk = D.getTypeObject(N-I-1);
|
||||
if (Chunk.Kind == DeclaratorChunk::Function &&
|
||||
Chunk.Fun.TypeQuals != 0) {
|
||||
switch (Chunk.Fun.TypeQuals) {
|
||||
case Qualifiers::Const:
|
||||
Range = Chunk.Fun.getConstQualifierLoc();
|
||||
break;
|
||||
case Qualifiers::Volatile:
|
||||
Range = Chunk.Fun.getVolatileQualifierLoc();
|
||||
break;
|
||||
case Qualifiers::Const | Qualifiers::Volatile: {
|
||||
SourceLocation CLoc = Chunk.Fun.getConstQualifierLoc();
|
||||
SourceLocation VLoc = Chunk.Fun.getVolatileQualifierLoc();
|
||||
if (S.getSourceManager()
|
||||
.isBeforeInTranslationUnit(CLoc, VLoc)) {
|
||||
Range = SourceRange(CLoc, VLoc);
|
||||
} else {
|
||||
Range = SourceRange(VLoc, CLoc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
S.Diag(Range.getBegin(), diag::err_invalid_qualified_function_type)
|
||||
<< FixItHint::CreateRemoval(Range);
|
||||
} else
|
||||
S.Diag(D.getIdentifierLoc(),
|
||||
diag::err_invalid_qualified_typedef_function_type_use)
|
||||
<< FreeFunction;
|
||||
|
|
|
@ -107,4 +107,7 @@ void test (BD &br) {
|
|||
aPtr = br; // expected-error {{assigning to 'A *' from incompatible type 'B'; take the address with &}}
|
||||
}
|
||||
|
||||
void foo1() const {} // expected-error {{type qualifier is not allowed on this function}}
|
||||
void foo2() volatile {} // expected-error {{type qualifier is not allowed on this function}}
|
||||
void foo3() const volatile {} // expected-error {{type qualifier is not allowed on this function}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue