This fixes: http://llvm.org/bugs/show_bug.cgi?id=7824
I'm not entirely sure that this is the right approach, but after investigating a while lot, this seems to be the way that Declarators work. It also seems that the location information isn't preserved past it's use in Sema, through the Declarator.
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 3260a70..4d40a3d 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -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, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 948309a..28eff95 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -4048,6 +4048,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; @@ -4086,8 +4088,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)) { @@ -4129,7 +4134,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D, ParamInfo.data(), ParamInfo.size(), DS.getTypeQualifiers(), RefQualifierIsLValueRef, - RefQualifierLoc, + RefQualifierLoc, ConstQualifierLoc, + VolatileQualifierLoc, /*MutableLoc=*/SourceLocation(), ESpecType, ESpecRange.getBegin(), DynamicExceptions.data(), diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 8dff0be..eb4344b 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -2275,6 +2275,8 @@ ExprResult Parser::ParseBlockLiteralExpression() { 0, 0, 0, true, SourceLocation(), SourceLocation(), + SourceLocation(), + SourceLocation(), EST_None, SourceLocation(), 0, 0, 0, 0, diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 33348a9..fe4bfc8 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -748,6 +748,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( DS.getTypeQualifiers(), /*RefQualifierIsLValueRef=*/true, /*RefQualifierLoc=*/SourceLocation(), + /*ConstQualifierLoc=*/SourceLocation(), + /*VolatileQualifierLoc=*/SourceLocation(), MutableLoc, ESpecType, ESpecRange.getBegin(), DynamicExceptions.data(), diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index f0a763e..037368b 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -150,6 +150,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, + SourceLocation ConstQualifierLoc, + SourceLocation + VolatileQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, @@ -176,6 +179,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(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8d993ef..8cadec5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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), diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index d3a3996..af90be6 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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, @@ -2422,10 +2424,33 @@ 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(); + Range = + SourceRange(std::min(CLoc, VLoc), std::max(CLoc, VLoc)); + } + 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;
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits