Avoid 'autocast' reporting for function definition

A function may just transmit passed-by-reference parameter somewhere.
Requirement to explicitly write forward declaration in the same file
(.cpp-file) to avoid '#include' suggestion is impractical when that type
is already fwd-declared in the corresponding header.
'Autocast' may still make sense for header-defined functions, due to
unlimited number of possible callers, so analysis of those fuctions
is kept.

Both function declaration site handling and call site handling
are changed.
This commit is contained in:
Bolshakov 2022-07-14 15:53:45 +03:00 committed by Kim Gräsman
parent 8b3da1112e
commit 862812049a
5 changed files with 46 additions and 1 deletions

View File

@ -1484,6 +1484,8 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
GetFileEntry(call_expr), GetFileEntry(*fn_redecl))) {
continue;
}
if (fn_redecl->isThisDeclarationADefinition() && !IsInHeader(*fn_redecl))
continue;
for (set<const Type*>::iterator it = retval.begin();
it != retval.end(); ) {
if (!CodeAuthorWantsJustAForwardDeclare(*it, GetLocation(*fn_redecl))) {
@ -1768,6 +1770,11 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> {
while ((redecl = redecl->getPreviousDecl()))
ReportDeclUse(CurrentLoc(), redecl);
}
if (!IsInHeader(decl)) {
// No point in author-intent analysis of function definitions
// in source files.
return true;
}
} else {
// Make all our types forward-declarable...
current_ast_node()->set_in_forward_declare_context(true);

View File

@ -10,6 +10,7 @@
#include "iwyu_location_util.h"
#include "iwyu_ast_util.h"
#include "iwyu_port.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
@ -28,6 +29,7 @@ using clang::CXXMethodDecl;
using clang::CXXOperatorCallExpr;
using clang::ClassTemplateSpecializationDecl;
using clang::ConditionalOperator;
using clang::FileEntry;
using clang::FunctionDecl;
using clang::MemberExpr;
using clang::SourceLocation;
@ -170,4 +172,10 @@ bool IsInScratchSpace(SourceLocation loc) {
return StartsWith(PrintableLoc(GetSpellingLoc(loc)), "<scratch space>");
}
bool IsInHeader(const clang::Decl* decl) {
const FileEntry* containing_file = GetFileEntry(decl);
CHECK_(containing_file);
return !GlobalSourceManager()->isMainFile(*containing_file);
}
} // namespace include_what_you_use

View File

@ -228,6 +228,9 @@ inline bool IsBeforeInSameFile(const T& a, const U& b) {
return IsBeforeInTranslationUnit(a, b);
}
// Returns true if the given declaration is located in a header file.
bool IsInHeader(const clang::Decl*);
} // namespace include_what_you_use
#endif // INCLUDE_WHAT_YOU_USE_IWYU_LOCATION_UTIL_H_

View File

@ -22,6 +22,14 @@ int ImplicitCtorFn(IndirectWithImplicitCtor);
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h.*for autocast
int ImplicitCtorRefFn(const IndirectWithImplicitCtor&);
// Reporting types for "autocast" for header-defined functions still makes sense
// as opposed to function definitions in source files.
// IWYU: IndirectWithImplicitCtor needs a declaration
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h.*for autocast
inline int InlineImplicitCtorRefFn(const IndirectWithImplicitCtor&) {
return 1;
}
// Test parameter type uses that do not require special handling for "autocast".
int NoAutocastFn(
// A subtle c++ point: forward-declaring is ok for nonconst, because

View File

@ -22,6 +22,18 @@
#include "tests/cxx/implicit_ctor-d1.h"
// No reporting types for "autocast" for .cpp-file-local functions...
// IWYU: IndirectWithImplicitCtor needs a declaration
static int LocalFn(const IndirectWithImplicitCtor&) {
return 1;
}
// ... or for .cpp-file-definitions of functions declared in a header.
// IWYU: IndirectWithImplicitCtor needs a declaration
int ImplicitCtorRefFn(const IndirectWithImplicitCtor&) {
return 2;
}
// We don't need IndirectWithImplicitCtor even though we must convert to it.
int a = ImplicitCtorFn(1);
int b = ImplicitCtorRefFn(2);
@ -32,6 +44,13 @@ int c = ImplicitCtorFn(IndirectWithImplicitCtor(3));
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h
int d = ImplicitCtorRefFn(IndirectWithImplicitCtor(4));
// LocalFn doesn't provide IndirectWithImplicitCtor type info.
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h
int e = LocalFn(5);
// InlineImplicitCtorRefFn should provide parameter type info,
// hence no reporting.
int f = InlineImplicitCtorRefFn(6);
// Make sure we are responsible for the conversion when it's not for a
// function call.
// IWYU: IndirectWithImplicitCtor is...*implicit_ctor-i2.h
@ -48,7 +67,7 @@ tests/cxx/implicit_ctor.cc should add these lines:
tests/cxx/implicit_ctor.cc should remove these lines:
The full include-list for tests/cxx/implicit_ctor.cc:
#include "tests/cxx/implicit_ctor-d1.h" // for ImplicitCtorFn, ImplicitCtorRefFn
#include "tests/cxx/implicit_ctor-d1.h" // for ImplicitCtorFn, ImplicitCtorRefFn, InlineImplicitCtorRefFn
#include "tests/cxx/implicit_ctor-i2.h" // for IndirectWithImplicitCtor
***** IWYU_SUMMARY */