use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.
the class FunctionTemplateTest method testFunctionTemplateStructure.
@Test
void testFunctionTemplateStructure() throws Exception {
List<TranslationUnitDeclaration> result = TestUtils.analyze(List.of(Path.of(topLevel.toString(), "functionTemplate.cpp").toFile()), topLevel, true);
// This test checks the structure of FunctionTemplates without the TemplateExpansionPass
FunctionTemplateDeclaration functionTemplateDeclaration = TestUtils.subnodesOfType(result, FunctionTemplateDeclaration.class).get(0);
// Check FunctionTemplate Parameters
List<TypeParamDeclaration> typeParamDeclarations = TestUtils.subnodesOfType(result, TypeParamDeclaration.class);
assertEquals(1, typeParamDeclarations.size());
TypeParamDeclaration typeParamDeclaration = typeParamDeclarations.get(0);
assertEquals(typeParamDeclaration, functionTemplateDeclaration.getParameters().get(0));
ParameterizedType T = new ParameterizedType("T");
ObjectType intType = new ObjectType("int", Type.Storage.AUTO, new Type.Qualifier(), new ArrayList<>(), ObjectType.Modifier.SIGNED, true);
ObjectType floatType = new ObjectType("float", Type.Storage.AUTO, new Type.Qualifier(), new ArrayList<>(), ObjectType.Modifier.SIGNED, true);
assertEquals(T, typeParamDeclaration.getType());
assertEquals(intType, typeParamDeclaration.getDefault());
ParamVariableDeclaration N = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ParamVariableDeclaration.class), "N");
Literal<Integer> int2 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(2));
Literal<Integer> int3 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(3));
Literal<Integer> int5 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(5));
assertEquals(N, functionTemplateDeclaration.getParameters().get(1));
assertEquals(intType, N.getType());
assertEquals(5, ((Literal) N.getDefault()).getValue());
assertTrue(N.getPrevDFG().contains(int5));
assertTrue(N.getPrevDFG().contains(int3));
assertTrue(N.getPrevDFG().contains(int2));
// Check the realization
assertEquals(1, functionTemplateDeclaration.getRealization().size());
FunctionDeclaration fixed_multiply = functionTemplateDeclaration.getRealization().get(0);
assertEquals(T, fixed_multiply.getType());
ParamVariableDeclaration val = fixed_multiply.getParameters().get(0);
assertEquals(T, val.getType());
// Check the invokes
CallExpression callInt2 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, CallExpression.class), c -> c.getLocation().getRegion().getStartLine() == 12);
assertEquals(1, callInt2.getInvokes().size());
assertEquals(fixed_multiply, callInt2.getInvokes().get(0));
CallExpression callFloat3 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, CallExpression.class), c -> c.getLocation().getRegion().getStartLine() == 13);
assertEquals(1, callFloat3.getInvokes().size());
assertEquals(fixed_multiply, callFloat3.getInvokes().get(0));
// Check return values
assertEquals(intType, callInt2.getType());
assertEquals(floatType, callFloat3.getType());
// Check template arguments
testFunctionTemplateArguments(callFloat3, floatType, int3);
}
use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.
the class ClassTemplateTest method testReferenceInTemplates.
@Test
void testReferenceInTemplates() throws Exception {
// Test array.cpp: checks usage of referencetype of parameterized type (T[])
TypeManager.reset();
List<TranslationUnitDeclaration> result = TestUtils.analyze(List.of(Path.of(topLevel.toString(), "array.cpp").toFile()), topLevel, true);
ClassTemplateDeclaration template = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ClassTemplateDeclaration.class), "template<typename T, int N=10> class Array");
RecordDeclaration array = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, RecordDeclaration.class), "Array");
ParamVariableDeclaration N = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ParamVariableDeclaration.class), "N");
TypeParamDeclaration T = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, TypeParamDeclaration.class), "typename T");
Literal<?> literal10 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(10));
FieldDeclaration thisField = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "this");
FieldDeclaration m_Array = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "m_Array");
assertEquals(2, template.getParameters().size());
assertEquals(T, template.getParameters().get(0));
assertEquals(N, template.getParameters().get(1));
assertEquals(literal10, N.getDefault());
assertEquals(2, array.getFields().size());
assertEquals(thisField, array.getFields().get(0));
assertEquals(m_Array, array.getFields().get(1));
ObjectType arrayType = (ObjectType) thisField.getType();
assertEquals(1, arrayType.getGenerics().size());
assertEquals("T", arrayType.getGenerics().get(0).getName());
ParameterizedType typeT = (ParameterizedType) arrayType.getGenerics().get(0);
assertEquals(typeT, T.getType());
assertTrue(m_Array.getType() instanceof PointerType);
PointerType tArray = (PointerType) m_Array.getType();
assertEquals(typeT, tArray.getElementType());
ConstructExpression constructExpression = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, ConstructExpression.class), c -> c.getCode().equals("()"));
assertEquals(template, constructExpression.getTemplateInstantiation());
assertEquals(array, constructExpression.getInstantiates());
assertEquals("int", constructExpression.getTemplateParameters().get(0).getName());
assertEquals(literal10, constructExpression.getTemplateParameters().get(1));
assertEquals("Array", constructExpression.getType().getName());
ObjectType instantiatedType = (ObjectType) constructExpression.getType();
assertEquals(1, instantiatedType.getGenerics().size());
assertEquals("int", instantiatedType.getGenerics().get(0).getName());
}
use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.
the class ClassTemplateTest method testStructTemplateWithSameDefaultType.
@Test
void testStructTemplateWithSameDefaultType() throws Exception {
// Test pair3.cpp: Template a struct instead of a class and use a Type1 as default of Type2
TypeManager.reset();
List<TranslationUnitDeclaration> result = TestUtils.analyze(List.of(Path.of(topLevel.toString(), "pair3.cpp").toFile()), topLevel, true);
ClassTemplateDeclaration template = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ClassTemplateDeclaration.class), "template<class Type1, class Type2 = Type1> struct Pair");
RecordDeclaration pair = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, RecordDeclaration.class), "Pair");
ConstructorDeclaration pairConstructorDeclaration = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ConstructorDeclaration.class), "Pair");
TypeParamDeclaration type1 = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, TypeParamDeclaration.class), "class Type1");
TypeParamDeclaration type2 = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, TypeParamDeclaration.class), "class Type2 = Type1");
FieldDeclaration first = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "first");
FieldDeclaration second = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "second");
VariableDeclaration point1 = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, VariableDeclaration.class), "point1");
ConstructExpression constructExpression = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, ConstructExpression.class), c -> c.getCode().equals("()"));
assertEquals(1, template.getRealization().size());
assertEquals(pair, template.getRealization().get(0));
assertEquals(2, template.getParameters().size());
assertEquals(type1, template.getParameters().get(0));
assertEquals(type2, template.getParameters().get(1));
assertEquals("Type1", type1.getType().getName());
ParameterizedType type1ParameterizedType = (ParameterizedType) type1.getType();
assertEquals("Type2", type2.getType().getName());
ParameterizedType type2ParameterizedType = (ParameterizedType) type2.getType();
assertEquals(type1ParameterizedType, type2.getDefault());
ObjectType pairType = (ObjectType) pairConstructorDeclaration.getType();
assertEquals(2, pairType.getGenerics().size());
assertEquals(type1ParameterizedType, pairType.getGenerics().get(0));
assertEquals(type2ParameterizedType, pairType.getGenerics().get(1));
// cpp has implicit `this` field
assertEquals(3, pair.getFields().size());
assertEquals(first, pair.getFields().get(1));
assertEquals(second, pair.getFields().get(2));
assertEquals(type1ParameterizedType, first.getType());
assertEquals(type2ParameterizedType, second.getType());
testStructTemplateWithSameDefaultTypeInvocation(template, pair, pairConstructorDeclaration, constructExpression, point1);
}
use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.
the class DeclarationHandler method handleFieldDeclaration.
public de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration handleFieldDeclaration(com.github.javaparser.ast.body.FieldDeclaration fieldDecl) {
// TODO: can field have more than one variable?
VariableDeclarator variable = fieldDecl.getVariable(0);
List<String> modifiers = fieldDecl.getModifiers().stream().map(modifier -> modifier.getKeyword().asString()).collect(Collectors.toList());
String joinedModifiers = String.join(" ", modifiers) + " ";
PhysicalLocation location = this.lang.getLocationFromRawNode(fieldDecl);
Expression initializer = (Expression) variable.getInitializer().map(this.lang.getExpressionHandler()::handle).orElse(null);
Type type;
try {
// Resolve type first with ParameterizedType
type = TypeManager.getInstance().getTypeParameter(this.lang.getScopeManager().getCurrentRecord(), variable.resolve().getType().describe());
if (type == null) {
type = TypeParser.createFrom(joinedModifiers + variable.resolve().getType().describe(), true);
}
} catch (UnsolvedSymbolException | UnsupportedOperationException e) {
String t = this.lang.recoverTypeFromUnsolvedException(e);
if (t == null) {
log.warn("Could not resolve type for {}", variable);
type = TypeParser.createFrom(joinedModifiers + variable.getType().asString(), true);
} else {
type = TypeParser.createFrom(joinedModifiers + t, true);
type.setTypeOrigin(Type.Origin.GUESSED);
}
}
de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration fieldDeclaration = newFieldDeclaration(variable.getName().asString(), type, modifiers, variable.toString(), location, initializer, false);
lang.getScopeManager().addDeclaration(fieldDeclaration);
this.lang.processAnnotations(fieldDeclaration, fieldDecl);
return fieldDeclaration;
}
use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.
the class DeclarationHandler method handleClassOrInterfaceDeclaration.
public RecordDeclaration handleClassOrInterfaceDeclaration(ClassOrInterfaceDeclaration classInterDecl) {
// TODO: support other kinds, such as interfaces
String fqn = classInterDecl.getNameAsString();
// Todo adapt name using a new type of scope "Namespace/Package scope"
// if (packageDeclaration != null) {
// name = packageDeclaration.getNameAsString() + "." + name;
// }
fqn = getAbsoluteName(fqn);
// add a type declaration
RecordDeclaration recordDeclaration = newRecordDeclaration(fqn, "class", null, true, lang, classInterDecl);
recordDeclaration.setSuperClasses(classInterDecl.getExtendedTypes().stream().map(this.lang::getTypeAsGoodAsPossible).collect(Collectors.toList()));
recordDeclaration.setImplementedInterfaces(classInterDecl.getImplementedTypes().stream().map(this.lang::getTypeAsGoodAsPossible).collect(Collectors.toList()));
TypeManager.getInstance().addTypeParameter(recordDeclaration, classInterDecl.getTypeParameters().stream().map(t -> new ParameterizedType(t.getNameAsString())).collect(Collectors.toList()));
Map<Boolean, List<String>> partitioned = this.lang.getContext().getImports().stream().collect(Collectors.partitioningBy(ImportDeclaration::isStatic, Collectors.mapping(i -> {
String iName = i.getNameAsString();
// we need to ensure that x.* imports really preserve the asterisk!
if (i.isAsterisk() && !iName.endsWith(".*")) {
iName += ".*";
}
return iName;
}, Collectors.toList())));
recordDeclaration.setStaticImportStatements(partitioned.get(true));
recordDeclaration.setImportStatements(partitioned.get(false));
lang.getScopeManager().enterScope(recordDeclaration);
lang.getScopeManager().addDeclaration(recordDeclaration.getThis());
// TODO: 'this' identifier for multiple instances?
for (BodyDeclaration<?> decl : classInterDecl.getMembers()) {
if (decl instanceof com.github.javaparser.ast.body.FieldDeclaration) {
// will be added via the scopemanager
handle(decl);
} else if (decl instanceof com.github.javaparser.ast.body.MethodDeclaration) {
de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration md = (de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration) handle(decl);
recordDeclaration.addMethod(md);
} else if (decl instanceof com.github.javaparser.ast.body.ConstructorDeclaration) {
de.fraunhofer.aisec.cpg.graph.declarations.ConstructorDeclaration c = (de.fraunhofer.aisec.cpg.graph.declarations.ConstructorDeclaration) handle(decl);
recordDeclaration.addConstructor(c);
} else if (decl instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) {
recordDeclaration.addDeclaration(handle(decl));
} else if (decl instanceof com.github.javaparser.ast.body.InitializerDeclaration) {
InitializerDeclaration id = (InitializerDeclaration) decl;
CompoundStatement initializerBlock = lang.getStatementHandler().handleBlockStatement(id.getBody());
initializerBlock.setStaticBlock(id.isStatic());
recordDeclaration.addStatement(initializerBlock);
} else {
log.debug("Member {} of type {} is something that we do not parse yet: {}", decl, recordDeclaration.getName(), decl.getClass().getSimpleName());
}
}
if (recordDeclaration.getConstructors().isEmpty()) {
de.fraunhofer.aisec.cpg.graph.declarations.ConstructorDeclaration constructorDeclaration = newConstructorDeclaration(recordDeclaration.getName(), recordDeclaration.getName(), recordDeclaration);
recordDeclaration.addConstructor(constructorDeclaration);
lang.getScopeManager().addDeclaration(constructorDeclaration);
}
lang.processAnnotations(recordDeclaration, classInterDecl);
lang.getScopeManager().leaveScope(recordDeclaration);
return recordDeclaration;
}
Aggregations