use of de.fraunhofer.aisec.cpg.graph.types.FunctionPointerType in project cpg by Fraunhofer-AISEC.
the class Expression method setType.
@Override
public void setType(Type type, HasType root) {
if (!TypeManager.isTypeSystemActive()) {
TypeManager.getInstance().cacheType(this, type);
return;
}
// performs less than optimal.
if (type == null || root == this) {
return;
}
if (this.type instanceof FunctionPointerType && !(type instanceof FunctionPointerType)) {
return;
}
Type oldType = this.type;
if (TypeManager.getInstance().isUnknown(type) || TypeManager.getInstance().stopPropagation(oldType, type)) {
return;
}
type = type.duplicate();
type.setQualifier(this.type.getQualifier().merge(type.getQualifier()));
Set<Type> subTypes = new HashSet<>();
for (Type t : getPossibleSubTypes()) {
if (!t.isSimilar(type)) {
subTypes.add(t);
}
}
subTypes.add(type);
this.type = TypeManager.getInstance().registerType(TypeManager.getInstance().getCommonType(subTypes).orElse(type));
subTypes = subTypes.stream().filter(s -> TypeManager.getInstance().isSupertypeOf(this.type, s)).collect(Collectors.toSet());
subTypes = subTypes.stream().map(s -> TypeManager.getInstance().registerType(s)).collect(Collectors.toSet());
setPossibleSubTypes(subTypes);
if (!Objects.equals(oldType, type)) {
this.typeListeners.stream().filter(l -> !l.equals(this)).forEach(l -> l.typeChanged(this, root == null ? this : root, oldType));
}
}
use of de.fraunhofer.aisec.cpg.graph.types.FunctionPointerType in project cpg by Fraunhofer-AISEC.
the class Expression method setType.
@Override
public void setType(Type type, Collection<HasType> root) {
if (!TypeManager.isTypeSystemActive()) {
this.type = type;
TypeManager.getInstance().cacheType(this, type);
return;
}
if (root == null) {
root = new ArrayList<>();
}
// No (or only unknown) type given, loop detected? Stop early because there's nothing we can do.
if (type == null || root.contains(this) || TypeManager.getInstance().isUnknown(type) || TypeManager.getInstance().stopPropagation(this.type, type) || (this.type instanceof FunctionPointerType && !(type instanceof FunctionPointerType))) {
return;
}
// Backup to check if something changed
Type oldType = this.type;
type = type.duplicate();
type.setQualifier(this.type.getQualifier().merge(type.getQualifier()));
Set<Type> subTypes = new HashSet<>();
// Check all current subtypes and consider only those which are "different enough" to type.
for (Type t : getPossibleSubTypes()) {
if (!t.isSimilar(type)) {
subTypes.add(t);
}
}
subTypes.add(type);
// Probably tries to get something like the best supertype of all possible subtypes.
this.type = TypeManager.getInstance().registerType(TypeManager.getInstance().getCommonType(subTypes).orElse(type));
// TODO: Why do we need this loop? Shouldn't the condition be ensured by the previous line
// getting the common type??
Set<Type> newSubtypes = new HashSet<>();
for (var s : subTypes) {
if (TypeManager.getInstance().isSupertypeOf(this.type, s)) {
newSubtypes.add(TypeManager.getInstance().registerType(s));
}
}
setPossibleSubTypes(newSubtypes);
if (Objects.equals(oldType, type)) {
// Nothing changed, so we do not have to notify the listeners.
return;
}
// Add current node to the set of "triggers" to detect potential loops.
root.add(this);
// Notify all listeners about the changed type
for (var l : typeListeners) {
if (!l.equals(this)) {
l.typeChanged(this, root, oldType);
}
}
}
use of de.fraunhofer.aisec.cpg.graph.types.FunctionPointerType in project cpg by Fraunhofer-AISEC.
the class ValueDeclaration method setType.
@Override
public void setType(Type type, Collection<HasType> root) {
if (!TypeManager.isTypeSystemActive()) {
TypeManager.getInstance().cacheType(this, type);
return;
}
if (root == null) {
root = new ArrayList<>();
}
if (type == null || root.contains(this) || TypeManager.getInstance().isUnknown(type) || (this.type instanceof FunctionPointerType && !(type instanceof FunctionPointerType))) {
return;
}
Type oldType = this.type;
type = type.duplicate();
type.setQualifier(this.type.getQualifier().merge(type.getQualifier()));
Set<Type> subTypes = new HashSet<>();
for (Type t : getPossibleSubTypes()) {
if (!t.isSimilar(type)) {
subTypes.add(t);
}
}
subTypes.add(type);
this.type = TypeManager.getInstance().registerType(TypeManager.getInstance().getCommonType(subTypes).orElse(type));
Set<Type> newSubtypes = new HashSet<>();
for (var s : subTypes) {
if (TypeManager.getInstance().isSupertypeOf(this.type, s)) {
newSubtypes.add(TypeManager.getInstance().registerType(s));
}
}
setPossibleSubTypes(newSubtypes);
if (Objects.equals(oldType, type)) {
// Nothing changed, so we do not have to notify the listeners.
return;
}
// Add current node to the set of "triggers" to detect potential loops.
root.add(this);
// Notify all listeners about the changed type
for (var l : typeListeners) {
if (!l.equals(this)) {
l.typeChanged(this, root, oldType);
}
}
}
use of de.fraunhofer.aisec.cpg.graph.types.FunctionPointerType in project cpg by Fraunhofer-AISEC.
the class Util method generateParamName.
private static String generateParamName(int i, @NonNull Type targetType) {
Deque<String> hierarchy = new ArrayDeque<>();
Type currLevel = targetType;
while (currLevel != null) {
if (currLevel instanceof FunctionPointerType) {
hierarchy.push("Fptr");
currLevel = null;
} else if (currLevel instanceof PointerType) {
hierarchy.push("Ptr");
currLevel = ((PointerType) currLevel).getElementType();
} else if (currLevel instanceof ReferenceType) {
hierarchy.push("Ref");
currLevel = ((ReferenceType) currLevel).getElementType();
} else {
hierarchy.push(currLevel.getTypeName());
currLevel = null;
}
}
StringBuilder paramName = new StringBuilder();
while (!hierarchy.isEmpty()) {
String part = hierarchy.pop();
if (part.isEmpty()) {
continue;
}
if (paramName.length() > 0) {
paramName.append(part.substring(0, 1).toUpperCase());
if (part.length() >= 2) {
paramName.append(part.substring(1));
}
} else {
paramName.append(part.toLowerCase());
}
}
paramName.append(i);
return paramName.toString();
}
use of de.fraunhofer.aisec.cpg.graph.types.FunctionPointerType in project cpg by Fraunhofer-AISEC.
the class ValueDeclaration method setType.
@Override
public void setType(Type type, HasType root) {
if (!TypeManager.isTypeSystemActive()) {
TypeManager.getInstance().cacheType(this, type);
return;
}
if (type == null || root == this) {
return;
}
if (this.type instanceof FunctionPointerType && !(type instanceof FunctionPointerType)) {
return;
}
Type oldType = this.type;
if (TypeManager.getInstance().isUnknown(type)) {
return;
}
type = type.duplicate();
type.setQualifier(this.type.getQualifier().merge(type.getQualifier()));
Set<Type> subTypes = new HashSet<>();
for (Type t : getPossibleSubTypes()) {
if (!t.isSimilar(type)) {
subTypes.add(t);
}
}
subTypes.add(type);
this.type = TypeManager.getInstance().registerType(TypeManager.getInstance().getCommonType(subTypes).orElse(type));
subTypes = subTypes.stream().filter(s -> TypeManager.getInstance().isSupertypeOf(this.type, s)).collect(Collectors.toSet());
subTypes = subTypes.stream().map(s -> TypeManager.getInstance().registerType(s)).collect(Collectors.toSet());
setPossibleSubTypes(subTypes);
if (!Objects.equals(oldType, type)) {
this.typeListeners.stream().filter(l -> !l.equals(this)).forEach(l -> l.typeChanged(this, root == null ? this : root, oldType));
}
}
Aggregations