use of de.fraunhofer.aisec.cpg.graph.TypeManager in project cpg by Fraunhofer-AISEC.
the class TypeParser method createFromUnsafe.
/**
* Warning: This function might crash, when a type cannot be parsed. Use createFrom instead Use
* this function for parsing new types and obtaining a new Type the TypeParser creates from the
* typeString
*
* @param type string with type information
* @param resolveAlias should replace with original type in typedefs
* @return new type representing the type string
*/
@NonNull
private static Type createFromUnsafe(@NonNull String type, boolean resolveAlias) {
// Check if Problems during Parsing
if (!checkValidTypeString(type)) {
return UnknownType.getUnknownType();
}
// Preprocessing of the typeString
type = removeAccessModifier(type);
// Remove CPP :: Operator
type = replaceScopeResolutionOperator(type);
// Determine if inner class
type = fixGenerics(type);
// Separate typeString into a List containing each part of the typeString
List<String> typeBlocks = separate(type);
// Depending if the Type is primitive or not signed/unsigned must be set differently (only
// relevant for ObjectTypes)
boolean primitiveType = isPrimitiveType(typeBlocks);
// Default is signed, unless unsigned keyword is specified. For other classes that are not
// primitive this is NOT_APPLICABLE
ObjectType.Modifier modifier = determineModifier(typeBlocks, primitiveType);
// Join compound primitive types into one block i.e. types consisting of more than one word e.g.
// long long int (only primitive types)
typeBlocks = joinPrimitive(typeBlocks);
List<String> qualifierList = new ArrayList<>();
List<String> storageList = new ArrayList<>();
// Handle preceding qualifier or storage specifier to the type name e.g. static const int
int counter = 0;
for (String part : typeBlocks) {
if (isQualifierSpecifier(part)) {
qualifierList.add(part);
counter++;
} else if (isStorageSpecifier(part)) {
storageList.add(part);
counter++;
} else if (isElaboratedTypeSpecifier(part)) {
// ignore elaborated types for now
counter++;
} else {
break;
}
}
Type.Storage storageValue = calcStorage(storageList);
Type.Qualifier qualifier = calcQualifier(qualifierList, null);
// Once all preceding known keywords (if any) are handled the next word must be the TypeName
if (counter >= typeBlocks.size()) {
// Note that "const auto ..." will end here with typeName="const" as auto is not supported.
return UnknownType.getUnknownType();
}
String typeName = typeBlocks.get(counter);
counter++;
Type finalType;
TypeManager typeManager = TypeManager.getInstance();
// Check if type is FunctionPointer
Matcher funcptr = getFunctionPtrMatcher(typeBlocks.subList(counter, typeBlocks.size()));
if (funcptr != null) {
Type returnType = createFrom(typeName, false);
List<Type> parameterList = getParameterList(funcptr.group("args"));
return typeManager.registerType(new FunctionPointerType(qualifier, storageValue, parameterList, returnType));
} else if (isIncompleteType(typeName)) {
// IncompleteType e.g. void
finalType = new IncompleteType();
} else if (isUnknownType(typeName)) {
// UnknownType -> no information on how to process this type
finalType = new UnknownType(UNKNOWN_TYPE_STRING);
} else {
// ObjectType
// Obtain possible generic List from TypeString
List<Type> generics = getGenerics(typeName);
typeName = removeGenerics(typeName);
finalType = new ObjectType(typeName, storageValue, qualifier, generics, modifier, primitiveType);
}
if (finalType.getTypeName().equals("auto") || (type.contains("auto") && !primitiveType)) {
// dataflow
return UnknownType.getUnknownType();
}
// Process Keywords / Operators (*, &) after typeName
List<String> subPart = typeBlocks.subList(counter, typeBlocks.size());
List<String> bracketExpressions = new ArrayList<>();
finalType = postTypeParsing(subPart, finalType, bracketExpressions);
// Resolve BracketExpressions that were identified previously
finalType = resolveBracketExpression(finalType, bracketExpressions);
// Make sure, that only one real instance exists for a type in order to have just one node in
// the graph representing the type
finalType = typeManager.registerType(finalType);
if (resolveAlias) {
return typeManager.registerType(typeManager.resolvePossibleTypedef(finalType));
}
return finalType;
}
use of de.fraunhofer.aisec.cpg.graph.TypeManager in project cpg by Fraunhofer-AISEC.
the class JavaExternalTypeHierarchyResolver method accept.
@Override
public void accept(TranslationResult translationResult) {
// Run only for Java.
if (this.lang instanceof JavaLanguageFrontend) {
TypeSolver resolver = ((JavaLanguageFrontend) this.lang).getNativeTypeResolver();
TypeManager tm = TypeManager.getInstance();
// Iterate over all known types and add their (direct) supertypes.
for (Type t : new HashSet<>(tm.getFirstOrderTypes())) {
SymbolReference<ResolvedReferenceTypeDeclaration> symbol = resolver.tryToSolveType(t.getTypeName());
if (symbol.isSolved()) {
try {
List<ResolvedReferenceType> resolvedSuperTypes = symbol.getCorrespondingDeclaration().getAncestors(true);
for (ResolvedReferenceType anc : resolvedSuperTypes) {
// Add all resolved supertypes to the type.
Type superType = TypeParser.createFrom(anc.getQualifiedName(), false);
superType.setTypeOrigin(Type.Origin.RESOLVED);
t.getSuperTypes().add(superType);
}
} catch (UnsolvedSymbolException e) {
// Even if the symbol itself is resolved, "getAnchestors()" may throw exception.
LOGGER.warn("Could not resolve supertypes of {}", symbol.getCorrespondingDeclaration());
}
}
}
}
}
Aggregations