Adds support for making pointers to C structs always import as OpaquePointer through API notes. This is needed to bring down the Android SDK to API level 23, since FILE is imported differently on API 23 vs 24.
We wrote the same code multiple times, this PR replaces some of that
code with function calls. It is not entirely NFC as the called function
has some special case for parameters. That being said, having uniform
logic for looking up attributes is probably beneficial. If it does not
work out, we can always introduce a compile-time parameter to opt in/out
of the special case.
This assertion is a sanity check but apparently fails in some scenarios
that I have yet to investigate. Suppressing this assertion is harmless;
nothing depends on the result of this call.
rdar://171995960
It was an unwieldy helper to begin with.
Also, add a comment about how the "considering inheritance" bit is not
actually the right thing to do in the first place. That behavior will
be deprecated Soon™️
Rename getCxxRefConventionWithAttrs() to getOwnershipOfReturnedFRT()
(since this isn't specific to C++)
Move it to ClangAnalysis.cpp and reuse some helper functions in there
rather than duplicating code.
Move around the checking logic a little so that it flows more
intuitively---check whether the warning should apply to the function
decl in the first place, *then* look at its return type and determine
whether the called function is missing annotations.
Also, we should never call deduction guides and destructors, so ASSERT
that we don't. We do occasionally call some decls this check doesn't
handle like FunctionTemplateDecls, BlockDecls, and VarDecls (of function
or block pointers), so make that explicit.
Moving this here gives us access to ClangImporter's internal APIs for
future improvements. It also keeps changes to interop-specific
diagnostics localized to the interop-specific part of the compiler.
This is unnecessary now that we only have a single call site from
SwiftDeclConverter::VisitCXXRecordDecl. The SwiftDeclConverter already
has its own cacheing to ensure that each Clang decl is only imported
once; that same cache ensures any diagnostics emitted during import
are also idempotent.
rdar://170858418
Previously, the getRefParentOrDiag() function was used both to determine
the reference typedness of an imported record, and to diagnose cases
where that determination was invalid (e.g., due to complications that
arise from inheritance). However, it exposed a rather brutish interface
for controlling whether diagnostics are emitted: when it is given
a non-null ClangImporter::Implementation pointer, it emits diagnostics,
and when given a null pointer it doesn't. A lack of consideration for
where we actually needed these diagnostics led to that pointer being
unnecessarily threaded through a couple of requests and a half dozen
call sites, leading to unnecessarily obscure control flow.
This patch gets rid of getRefParentOrDiag() and replaces it with two
well-defined entry points: a request that does not emit diagnostics, and
a function that does. The nullable ClangImporter::Implementation pointer
is hidden from the interface of those entry points, and their side
effects are well-documented.
The code is migrated from ClangImporter.cpp to ClangAnalysis.cpp, which
I've introduced as the new home for various subroutines that analyze and
extract information from clang decls.
The reference type inference logic of getRefParentOrDiag() (and its
associated helpers) is also rewritten to replace the clang-provided
clang::CXXRecordDecl::forAllBases() with an explicit graph traversal
through the class hierarchy that is easier to debug and adjust (with
imminent behavior changes in mind). It also avoids an unnecessary
class hierarchy traversal whose only purpose was to look for reference
types that participates in diamond inheritance.
No behavior change is intended: we (should) still make perform the same
reference typedness analysis, and emit the exact same diagnostics.
rdar://170858418