[cxx-interop] Fix generated declaration order

The generated thunks for functions can refer to some internal methods of
their arguments. As a result, those generated thunks should always be
after the definitions of the corresponding argument types. The printer
ordered the declarations by name, and Swift had the convention starting
types with upper case letters and functions with lower case letters.
This naming convention together with the ordering resulted in the
correct ordering in most of the cases. There were a couple of exceptions
when people diverged from the naming conventions or wanted to export
operators. This patch fixes this problem by always ordering type decls
before function decls.

rdar://129276354
This commit is contained in:
Gabor Horvath
2024-06-13 12:25:59 +01:00
parent 85c0555c89
commit dbdd983392
3 changed files with 17 additions and 9 deletions

View File

@@ -20,6 +20,7 @@
#include "PrintSwiftToClangCoreScaffold.h"
#include "SwiftToClangInteropContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/ExistentialLayout.h"
#include "swift/AST/Module.h"
@@ -671,6 +672,15 @@ public:
llvm_unreachable("unknown top-level ObjC decl");
};
// When we visit a function, we might also generate a thunk that calls into the
// implementation of structs/enums to get the opaque pointers. To avoid
// referencing these methods before we see the definition for the generated
// classes, we want to visit function definitions last.
if (isa<AbstractFunctionDecl>(*rhs) && isa<NominalTypeDecl>(*lhs))
return Descending;
if (isa<AbstractFunctionDecl>(*lhs) && isa<NominalTypeDecl>(*rhs))
return Ascending;
// Sort by names.
int result = getSortName(*rhs).compare(getSortName(*lhs));
if (result != 0)
@@ -700,9 +710,9 @@ public:
// even when the variable might not actually be emitted by the emitter.
// In that case, order the function before the variable.
if (isa<AbstractFunctionDecl>(*rhs) && isa<VarDecl>(*lhs))
return 1;
return Descending;
if (isa<AbstractFunctionDecl>(*lhs) && isa<VarDecl>(*rhs))
return -1;
return Ascending;
// Prefer value decls to extensions.
assert(!(isa<ValueDecl>(*lhs) && isa<ValueDecl>(*rhs)));