diff options
author | Alp Toker <alp@nuanti.com> | 2014-07-02 01:47:15 +0000 |
---|---|---|
committer | Alp Toker <alp@nuanti.com> | 2014-07-02 01:47:15 +0000 |
commit | d0787ebf5e769ce81c182f8685ca1f6d22d5c592 (patch) | |
tree | 28c991916adef4ef6c170eb5a2bb87ae177874fc /clang/lib/Sema/SemaDecl.cpp | |
parent | 5b336a242c7402f4aecd60ab42f0efa07dacbde8 (diff) | |
download | bcm5719-llvm-d0787ebf5e769ce81c182f8685ca1f6d22d5c592.tar.gz bcm5719-llvm-d0787ebf5e769ce81c182f8685ca1f6d22d5c592.zip |
Introduce a FunctionDecl::getReturnTypeSourceRange() utility
This source range is useful for all kinds of diagnostic QOI and refactoring
work, so let's make it more discoverable.
This commit also makes use of the new function to enhance various diagnostics
relating to return types and resolves an old FIXME.
llvm-svn: 212154
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 51 |
1 files changed, 18 insertions, 33 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ef2035c2907..849926327d0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2519,11 +2519,13 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType); if (ResQT.isNull()) { if (New->isCXXClassMember() && New->isOutOfLine()) - Diag(New->getLocation(), - diag::err_member_def_does_not_match_ret_type) << New; + Diag(New->getLocation(), diag::err_member_def_does_not_match_ret_type) + << New << New->getReturnTypeSourceRange(); else - Diag(New->getLocation(), diag::err_ovl_diff_return_type); - Diag(OldLocation, PrevDiag) << Old << Old->getType(); + Diag(New->getLocation(), diag::err_ovl_diff_return_type) + << New->getReturnTypeSourceRange(); + Diag(OldLocation, PrevDiag) << Old << Old->getType() + << Old->getReturnTypeSourceRange(); return true; } else @@ -7494,8 +7496,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // OpenCL v1.2, s6.9 -- Kernels can only have return type void. if (!NewFD->getReturnType()->isVoidType()) { - Diag(D.getIdentifierLoc(), - diag::err_expected_kernel_void_return_type); + SourceRange RTRange = NewFD->getReturnTypeSourceRange(); + Diag(D.getIdentifierLoc(), diag::err_expected_kernel_void_return_type) + << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void") + : FixItHint()); D.setInvalidType(); } @@ -7835,23 +7839,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, return Redeclaration; } -static SourceRange getResultSourceRange(const FunctionDecl *FD) { - const TypeSourceInfo *TSI = FD->getTypeSourceInfo(); - if (!TSI) - return SourceRange(); - - TypeLoc TL = TSI->getTypeLoc(); - FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>(); - if (!FunctionTL) - return SourceRange(); - - TypeLoc ResultTL = FunctionTL.getReturnLoc(); - if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>()) - return ResultTL.getSourceRange(); - - return SourceRange(); -} - void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { // C++11 [basic.start.main]p3: // A program that [...] declares main to be inline, static or @@ -7904,19 +7891,17 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint); - SourceRange ResultRange = getResultSourceRange(FD); - if (ResultRange.isValid()) - Diag(ResultRange.getBegin(), diag::note_main_change_return_type) - << FixItHint::CreateReplacement(ResultRange, "int"); + SourceRange RTRange = FD->getReturnTypeSourceRange(); + if (RTRange.isValid()) + Diag(RTRange.getBegin(), diag::note_main_change_return_type) + << FixItHint::CreateReplacement(RTRange, "int"); // Otherwise, this is just a flat-out error. } else { - SourceRange ResultRange = getResultSourceRange(FD); - if (ResultRange.isValid()) - Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint) - << FixItHint::CreateReplacement(ResultRange, "int"); - else - Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint); + SourceRange RTRange = FD->getReturnTypeSourceRange(); + Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint) + << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int") + : FixItHint()); FD->setInvalidDecl(true); } |