Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix parsing of template specializations and templated friend functions #733

Merged
merged 15 commits into from
Jan 9, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions src/main/java/org/bytedeco/javacpp/tools/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,40 @@ public Parser(Logger logger, Properties properties, String encoding, String line
String lineSeparator = null;
/** Java names of classes needing upcast from their subclasses. */
Set<String> upcasts = new HashSet<>();
/** Classes that have a base class appearing as key in this map need a downcast constructor. The associated value gives the class to downcast from. */
Map<String, Set<Type>> downcasts = new HashMap<>();

static private class Inheritance {
Type base;
boolean virtual;
HGuillemet marked this conversation as resolved.
Show resolved Hide resolved

public Inheritance(Type b, boolean v) {
base = b;
virtual = v;
}

@Override
public boolean equals(Object o) {
Inheritance i = (Inheritance) o;
return i != null && i.base.equals(base) && i.virtual == virtual;
}

@Override
public int hashCode() {
return base.hashCode() + (virtual ? 1 : 0);
}
}

/** Classes that have a base class appearing as a key in this map need a downcast constructor.
* The associated value gives the class to downcast from and whether the inheritance is virtual. */
Map<String, Set<Inheritance>> downcasts = new HashMap<>();
/** Java names of classes recognized as polymorphic. */
Set<String> polymorphicClasses = new HashSet<>();

private void addDowncast(String base, Type from) {
Set<Type> types = downcasts.get(base);
if (types == null) {
downcasts.put(base, types = new HashSet<>(1));
private void addDowncast(String base, Type from, boolean virtual) {
Set<Inheritance> inh = downcasts.get(base);
if (inh == null) {
downcasts.put(base, inh = new HashSet<>(1));
}
types.add(from);
inh.add(new Inheritance(from, virtual));
}

static String removeAnnotations(String s) {
Expand Down Expand Up @@ -3450,9 +3473,9 @@ boolean using(Context context, DeclarationList declList) throws ParserException
return true;
}

String downcast(Type derived, Type base) {
String downcast(Type derived, Type base, boolean virtual) {
final String downcastType;
if (base.virtual) {
if (virtual) {
if (polymorphicClasses.contains(base.javaName)) {
downcastType = "dynamic";
} else {
Expand Down Expand Up @@ -3676,10 +3699,10 @@ boolean group(Context context, DeclarationList declList) throws ParserException

/* Propagate the need for downcasting from base classes */
for (Type t : baseClasses) {
Set<Type> froms = downcasts.get(t.cppName);
Set<Inheritance> froms = downcasts.get(t.cppName);
if (froms != null) {
for (Type from : froms) {
addDowncast(type.cppName, from);
for (Inheritance from : froms) {
addDowncast(type.cppName, from.base, t.virtual || from.virtual);
}
}
}
Expand Down Expand Up @@ -3713,7 +3736,7 @@ boolean group(Context context, DeclarationList declList) throws ParserException
Info baseInfo = infoMap.getFirst(t.cppName);
if (!t.javaName.equals("Pointer") && (baseInfo == null || !baseInfo.skip)) {
casts += upcast(type, t, false);
addDowncast(t.cppName, t);
addDowncast(t.cppName, t, false);
}
}
}
Expand All @@ -3724,11 +3747,11 @@ boolean group(Context context, DeclarationList declList) throws ParserException
if (upcasts.contains(base.javaName)) {
// Base classes explicitly set as needing upcast in infoMap
casts += upcast(type, base, true);
addDowncast(base.cppName, base);
addDowncast(base.cppName, base, false);
} else if (polymorphicClasses.contains(base.javaName) && base.virtual) {
// In this case we know we need upcast
casts += upcast(type, base, false);
addDowncast(base.cppName, base);
addDowncast(base.cppName, base, false);
}

decl.signature = type.javaName;
Expand Down Expand Up @@ -3954,17 +3977,17 @@ boolean group(Context context, DeclarationList declList) throws ParserException
}
}

Set<Type> froms = downcasts.get(base.cppName);
for (Type t : froms != null ? froms : new HashSet<Type>()) {
Set<Inheritance> froms = downcasts.get(base.cppName);
for (Inheritance i : froms != null ? froms : new HashSet<Inheritance>()) {
boolean found = false;
for (Declaration d : declList2) {
if ((shortName + "_" + t.javaName).equals(d.signature)) {
if ((shortName + "_" + i.base.javaName).equals(d.signature)) {
found = true;
break;
}
}
if (!found) {
constructors += downcast(type, t);
constructors += downcast(type, i.base, i.virtual || base.virtual);
}
}

Expand Down