forked from OSchip/llvm-project
Make FunctionDecl::getReturnTypeSourceRange() support non-builtin types
Also document that the function is a "best-effort" facility to extract source ranges from limited AST type location info. llvm-svn: 212174
This commit is contained in:
parent
1471cb17ae
commit
f5b107940a
|
@ -1896,6 +1896,9 @@ public:
|
|||
return getType()->getAs<FunctionType>()->getReturnType();
|
||||
}
|
||||
|
||||
/// \brief Attempt to compute an informative source range covering the
|
||||
/// function return type. This may omit qualifiers and other information with
|
||||
/// limited representation in the AST.
|
||||
SourceRange getReturnTypeSourceRange() const;
|
||||
|
||||
/// \brief Determine the type of an expression that calls this function.
|
||||
|
|
|
@ -2691,17 +2691,20 @@ SourceRange FunctionDecl::getReturnTypeSourceRange() const {
|
|||
const TypeSourceInfo *TSI = getTypeSourceInfo();
|
||||
if (!TSI)
|
||||
return SourceRange();
|
||||
|
||||
TypeLoc TL = TSI->getTypeLoc();
|
||||
FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>();
|
||||
if (!FunctionTL)
|
||||
FunctionTypeLoc FTL =
|
||||
TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
|
||||
if (!FTL)
|
||||
return SourceRange();
|
||||
|
||||
TypeLoc ResultTL = FunctionTL.getReturnLoc();
|
||||
if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>())
|
||||
return ResultTL.getSourceRange();
|
||||
// Skip self-referential return types.
|
||||
const SourceManager &SM = getASTContext().getSourceManager();
|
||||
SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
|
||||
SourceLocation Boundary = getNameInfo().getLocStart();
|
||||
if (RTRange.isInvalid() || Boundary.isInvalid() ||
|
||||
!SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
|
||||
return SourceRange();
|
||||
|
||||
return SourceRange();
|
||||
return RTRange;
|
||||
}
|
||||
|
||||
/// \brief For an inline function definition in C, or for a gnu_inline function
|
||||
|
|
|
@ -3029,16 +3029,11 @@ static void handleOptimizeNoneAttr(Sema &S, Decl *D,
|
|||
static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
||||
FunctionDecl *FD = cast<FunctionDecl>(D);
|
||||
if (!FD->getReturnType()->isVoidType()) {
|
||||
TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
|
||||
if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
|
||||
S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
|
||||
SourceRange RTRange = FD->getReturnTypeSourceRange();
|
||||
S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
|
||||
<< FD->getType()
|
||||
<< FixItHint::CreateReplacement(FTL.getReturnLoc().getSourceRange(),
|
||||
"void");
|
||||
} else {
|
||||
S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
|
||||
<< FD->getType();
|
||||
}
|
||||
<< (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
|
||||
: FixItHint());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ double main() {
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
// Currently we suggest to replace only 'float' here because we don't store
|
||||
// enough source locations.
|
||||
// TODO: Store qualifier source locations for return types so
|
||||
// we can replace the full type with this fix-it.
|
||||
//
|
||||
// expected-error@+3 {{conflicting types for 'main}}
|
||||
// expected-warning@+2 {{return type of 'main' is not 'int'}}
|
||||
|
@ -35,9 +35,11 @@ const float main() {
|
|||
|
||||
typedef void *(*fptr)(int a);
|
||||
|
||||
// expected-error@+2 {{conflicting types for 'main}}
|
||||
// expected-warning@+1 {{return type of 'main' is not 'int'}}
|
||||
// expected-error@+3 {{conflicting types for 'main}}
|
||||
// expected-warning@+2 {{return type of 'main' is not 'int'}}
|
||||
// expected-note@+1 {{change return type to 'int'}}
|
||||
fptr main() {
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:1-[[@LINE-1]]:5}:"int"
|
||||
return (fptr) 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue