return getType()->getAs<FunctionType>()->getReturnType();
}
+ SourceRange getReturnTypeSourceRange() const;
+
/// \brief Determine the type of an expression that calls this function.
QualType getCallResultType() const {
return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
return FoundBody;
}
+SourceRange FunctionDecl::getReturnTypeSourceRange() const {
+ const TypeSourceInfo *TSI = 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();
+}
+
/// \brief For an inline function definition in C, or for a gnu_inline function
/// in C++, determine whether the definition will be externally visible.
///
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
// 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();
}
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
} 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);
}
if (NewClassTy.isNull()) {
Diag(New->getLocation(),
diag::err_different_return_type_for_overriding_virtual_function)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
}
if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
// Check if the new class derives from the old class.
if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
- Diag(New->getLocation(),
- diag::err_covariant_return_not_derived)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ Diag(New->getLocation(), diag::err_covariant_return_not_derived)
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
}
// Check if we the conversion from derived to base is valid.
- if (CheckDerivedToBaseConversion(NewClassTy, OldClassTy,
- diag::err_covariant_return_inaccessible_base,
- diag::err_covariant_return_ambiguous_derived_to_base_conv,
- // FIXME: Should this point to the return type?
- New->getLocation(), SourceRange(), New->getDeclName(),
- nullptr)) {
+ if (CheckDerivedToBaseConversion(
+ NewClassTy, OldClassTy,
+ diag::err_covariant_return_inaccessible_base,
+ diag::err_covariant_return_ambiguous_derived_to_base_conv,
+ New->getLocation(), New->getReturnTypeSourceRange(),
+ New->getDeclName(), nullptr)) {
// FIXME: this note won't trigger for delayed access control
// diagnostics, and it's impossible to get an undelayed error
// here from access control during the original parse because
// the ParsingDeclSpec/ParsingDeclarator are still in scope.
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
}
}
if (NewTy.getLocalCVRQualifiers() != OldTy.getLocalCVRQualifiers()) {
Diag(New->getLocation(),
diag::err_covariant_return_type_different_qualifications)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
};
if (NewClassTy.isMoreQualifiedThan(OldClassTy)) {
Diag(New->getLocation(),
diag::err_covariant_return_type_class_type_more_qualified)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
};