Search in sources :

Example 1 with TypeManager

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;
}
Also used : Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) TypeManager(de.fraunhofer.aisec.cpg.graph.TypeManager) NonNull(org.checkerframework.checker.nullness.qual.NonNull)

Example 2 with TypeManager

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());
                }
            }
        }
    }
}
Also used : UnsolvedSymbolException(com.github.javaparser.resolution.UnsolvedSymbolException) Type(de.fraunhofer.aisec.cpg.graph.types.Type) ResolvedReferenceType(com.github.javaparser.resolution.types.ResolvedReferenceType) ResolvedReferenceTypeDeclaration(com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration) ResolvedReferenceType(com.github.javaparser.resolution.types.ResolvedReferenceType) TypeSolver(com.github.javaparser.symbolsolver.model.resolution.TypeSolver) TypeManager(de.fraunhofer.aisec.cpg.graph.TypeManager) JavaLanguageFrontend(de.fraunhofer.aisec.cpg.frontends.java.JavaLanguageFrontend) HashSet(java.util.HashSet)

Aggregations

TypeManager (de.fraunhofer.aisec.cpg.graph.TypeManager)2 UnsolvedSymbolException (com.github.javaparser.resolution.UnsolvedSymbolException)1 ResolvedReferenceTypeDeclaration (com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration)1 ResolvedReferenceType (com.github.javaparser.resolution.types.ResolvedReferenceType)1 TypeSolver (com.github.javaparser.symbolsolver.model.resolution.TypeSolver)1 JavaLanguageFrontend (de.fraunhofer.aisec.cpg.frontends.java.JavaLanguageFrontend)1 Type (de.fraunhofer.aisec.cpg.graph.types.Type)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Matcher (java.util.regex.Matcher)1 NonNull (org.checkerframework.checker.nullness.qual.NonNull)1