diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala index 5a3aa2045a20..05606367c32e 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala @@ -41,20 +41,8 @@ import scala.annotation.nowarn import scala.collection.mutable import scala.util.Try -object AstCreatorHelper { - - implicit class OptionSafeAst(val ast: Ast) extends AnyVal { - def withArgEdge(src: NewNode, dst: Option[NewNode]): Ast = dst match { - case Some(value) => ast.withArgEdge(src, value) - case None => ast - } - } -} - trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: AstCreator => - import io.joern.c2cpg.astcreation.AstCreatorHelper.* - private var usedVariablePostfix: Int = 0 protected def isIncludedNode(node: IASTNode): Boolean = fileName(node) != filename @@ -195,9 +183,21 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As Try(expr.getEvaluation).toOption } + protected def safeGetBinding(name: IASTName): Option[IBinding] = { + // In case of unresolved includes etc. this may fail throwing an unrecoverable exception + Try(name.resolveBinding()).toOption + } + + protected def safeGetBinding(idExpression: IASTIdExpression): Option[IBinding] = { + // In case of unresolved includes etc. this may fail throwing an unrecoverable exception + safeGetBinding(idExpression.getName).collect { + case binding: IBinding if !binding.isInstanceOf[IProblemBinding] => binding + } + } + protected def safeGetBinding(spec: IASTNamedTypeSpecifier): Option[IBinding] = { // In case of unresolved includes etc. this may fail throwing an unrecoverable exception - Try(spec.getName.resolveBinding()).toOption.collect { + safeGetBinding(spec.getName).collect { case binding: IBinding if !binding.isInstanceOf[IProblemBinding] => binding } } @@ -335,7 +335,7 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As private def notHandledText(node: IASTNode): String = s"""Node '${node.getClass.getSimpleName}' not handled yet! - | Code: '${node.getRawSignature}' + | Code: '${shortenCode(node.getRawSignature)}' | File: '$filename' | Line: ${line(node).getOrElse(-1)} | """.stripMargin diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala index fe54429b697c..f5c52e702c87 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala @@ -78,46 +78,33 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { private def astForCppCallExpression(call: ICPPASTFunctionCallExpression): Ast = { val functionNameExpr = call.getFunctionNameExpression - val typ = functionNameExpr.getExpressionType - typ match { - case _: IPointerType => - createPointerCallAst(call, cleanType(safeGetType(call.getExpressionType))) - case functionType: ICPPFunctionType => + Try(functionNameExpr.getExpressionType).toOption match { + case Some(_: IPointerType) => createPointerCallAst(call, cleanType(safeGetType(call.getExpressionType))) + case Some(functionType: ICPPFunctionType) => functionNameExpr match { - case idExpr: CPPASTIdExpression if idExpr.getName.getBinding.isInstanceOf[ICPPFunction] => - val function = idExpr.getName.getBinding.asInstanceOf[ICPPFunction] - val name = idExpr.getName.getLastName.toString - val signature = - if (function.isExternC) { - "" - } else { - functionTypeToSignature(functionType) - } - - val fullName = - if (function.isExternC) { - StringUtils.normalizeSpace(name) - } else { - val fullNameNoSig = StringUtils.normalizeSpace(function.getQualifiedName.mkString(".")) - s"$fullNameNoSig:$signature" - } - - val dispatchType = DispatchTypes.STATIC_DISPATCH - + case idExpr: CPPASTIdExpression if safeGetBinding(idExpr).exists(_.isInstanceOf[ICPPFunction]) => + val function = idExpr.getName.getBinding.asInstanceOf[ICPPFunction] + val name = idExpr.getName.getLastName.toString + val signature = if function.isExternC then "" else functionTypeToSignature(functionType) + val fullName = if (function.isExternC) { + StringUtils.normalizeSpace(name) + } else { + val fullNameNoSig = StringUtils.normalizeSpace(function.getQualifiedName.mkString(".")) + s"$fullNameNoSig:$signature" + } val callCpgNode = callNode( call, code(call), name, fullName, - dispatchType, + DispatchTypes.STATIC_DISPATCH, Some(signature), Some(registerType(cleanType(safeGetType(call.getExpressionType)))) ) val args = call.getArguments.toList.map(a => astForNode(a)) - createCallAst(callCpgNode, args) case fieldRefExpr: ICPPASTFieldReference - if fieldRefExpr.getFieldName.resolveBinding().isInstanceOf[ICPPMethod] => + if safeGetBinding(fieldRefExpr.getFieldName).exists(_.isInstanceOf[ICPPMethod]) => val instanceAst = astForExpression(fieldRefExpr.getFieldOwner) val args = call.getArguments.toList.map(a => astForNode(a)) @@ -148,36 +135,29 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { case _ => astForCppCallExpressionUntyped(call) } - case classType: ICPPClassType if call.getEvaluation.isInstanceOf[EvalFunctionCall] => - val evaluation = call.getEvaluation.asInstanceOf[EvalFunctionCall] - + case Some(classType: ICPPClassType) if safeGetEvaluation(call).exists(_.isInstanceOf[EvalFunctionCall]) => + val evaluation = call.getEvaluation.asInstanceOf[EvalFunctionCall] val functionType = Try(evaluation.getOverload.getType).toOption val signature = functionType.map(functionTypeToSignature).getOrElse(X2CpgDefines.UnresolvedSignature) val name = Defines.OperatorCall - classType match { case _: CPPClosureType => - val fullName = s"$name:$signature" - val dispatchType = DispatchTypes.DYNAMIC_DISPATCH - + val fullName = s"$name:$signature" val callCpgNode = callNode( call, code(call), name, fullName, - dispatchType, + DispatchTypes.DYNAMIC_DISPATCH, Some(signature), Some(registerType(cleanType(safeGetType(call.getExpressionType)))) ) - val receiverAst = astForExpression(functionNameExpr) val args = call.getArguments.toList.map(a => astForNode(a)) - createCallAst(callCpgNode, args, receiver = Some(receiverAst)) case _ => val classFullName = cleanType(safeGetType(classType)) val fullName = s"$classFullName.$name:$signature" - val dispatchType = evaluation.getOverload match { case method: ICPPMethod => if (method.isVirtual || method.isPureVirtual) { @@ -197,17 +177,11 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { Some(signature), Some(registerType(cleanType(safeGetType(call.getExpressionType)))) ) - val instanceAst = astForExpression(functionNameExpr) val args = call.getArguments.toList.map(a => astForNode(a)) createCallAst(callCpgNode, args, base = Some(instanceAst), receiver = Some(instanceAst)) } - case _: IProblemType => - astForCppCallExpressionUntyped(call) - case _: IProblemBinding => - astForCppCallExpressionUntyped(call) - case _ => - astForCppCallExpressionUntyped(call) + case _ => astForCppCallExpressionUntyped(call) } } @@ -216,11 +190,9 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { case fieldRefExpr: ICPPASTFieldReference => val instanceAst = astForExpression(fieldRefExpr.getFieldOwner) val args = call.getArguments.toList.map(a => astForNode(a)) - - val name = StringUtils.normalizeSpace(fieldRefExpr.getFieldName.toString) - val signature = X2CpgDefines.UnresolvedSignature - val fullName = s"${X2CpgDefines.UnresolvedNamespace}.$name:$signature(${args.size})" - + val name = StringUtils.normalizeSpace(fieldRefExpr.getFieldName.toString) + val signature = X2CpgDefines.UnresolvedSignature + val fullName = s"${X2CpgDefines.UnresolvedNamespace}.$name:$signature(${args.size})" val callCpgNode = callNode( call, code(call), @@ -232,12 +204,10 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { ) createCallAst(callCpgNode, args, base = Some(instanceAst), receiver = Some(instanceAst)) case idExpr: CPPASTIdExpression => - val args = call.getArguments.toList.map(a => astForNode(a)) - + val args = call.getArguments.toList.map(a => astForNode(a)) val name = StringUtils.normalizeSpace(idExpr.getName.getLastName.toString) val signature = X2CpgDefines.UnresolvedSignature val fullName = s"${X2CpgDefines.UnresolvedNamespace}.$name:$signature(${args.size})" - val callCpgNode = callNode( call, code(call), @@ -251,12 +221,10 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { case otherExpr => // This could either be a pointer or an operator() call we do not know at this point // but since it is CPP we opt for the latter. - val args = call.getArguments.toList.map(a => astForNode(a)) - + val args = call.getArguments.toList.map(a => astForNode(a)) val name = Defines.OperatorCall val signature = X2CpgDefines.UnresolvedSignature val fullName = s"${X2CpgDefines.UnresolvedNamespace}.$name:$signature(${args.size})" - val callCpgNode = callNode( call, code(call), @@ -273,11 +241,10 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { private def astForCCallExpression(call: CASTFunctionCallExpression): Ast = { val functionNameExpr = call.getFunctionNameExpression - val typ = functionNameExpr.getExpressionType - typ match { - case _: CPointerType => + Try(functionNameExpr.getExpressionType).toOption match { + case Some(_: CPointerType) => createPointerCallAst(call, cleanType(safeGetType(call.getExpressionType))) - case _: CFunctionType => + case Some(_: CFunctionType) => functionNameExpr match { case idExpr: CASTIdExpression => createCFunctionCallAst(call, idExpr, cleanType(safeGetType(call.getExpressionType))) @@ -316,8 +283,7 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { } private def astForCCallExpressionUntyped(call: CASTFunctionCallExpression): Ast = { - val functionNameExpr = call.getFunctionNameExpression - functionNameExpr match { + call.getFunctionNameExpression match { case idExpr: CASTIdExpression => createCFunctionCallAst(call, idExpr, X2CpgDefines.Any) case _ => createPointerCallAst(call, X2CpgDefines.Any) } @@ -332,8 +298,7 @@ trait AstForExpressionsCreator(implicit withSchemaValidation: ValidationMode) { private def astForThrowExpression(expression: IASTUnaryExpression): Ast = { val operand = nullSafeAst(expression.getOperand) - Ast(controlStructureNode(expression, ControlStructureTypes.THROW, code(expression))) - .withChild(operand) + Ast(controlStructureNode(expression, ControlStructureTypes.THROW, code(expression))).withChild(operand) } private def astForUnaryExpression(unary: IASTUnaryExpression): Ast = { diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForFunctionsCreator.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForFunctionsCreator.scala index 1a6797e59377..e1c2942429db 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForFunctionsCreator.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForFunctionsCreator.scala @@ -22,6 +22,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeration import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPStructuredBindingComposite +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable import org.eclipse.cdt.internal.core.model.ASTStringUtil import scala.annotation.tailrec @@ -134,8 +135,8 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th } protected def astForFunctionDeclarator(funcDecl: IASTFunctionDeclarator): Ast = { - funcDecl.getName.resolveBinding() match { - case _: IFunction => + safeGetBinding(funcDecl.getName) match { + case Some(_: IFunction) => val MethodFullNameInfo(name, fullName, signature, returnType) = this.methodFullNameInfo(funcDecl) val codeString = code(funcDecl.getParent) val filename = fileName(funcDecl) @@ -165,14 +166,21 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th ) registerMethodDeclaration(fullName, methodInfo) Ast() - case cVariable: CVariable => + case Some(cVariable: CVariable) => val name = shortName(funcDecl) - val tpe = cleanType(ASTTypeUtil.getType(cVariable.getType)) + val tpe = cleanType(safeGetType(cVariable.getType)) val codeString = code(funcDecl.getParent) val node = localNode(funcDecl, name, codeString, registerType(tpe)) scope.addToScope(name, (node, tpe)) Ast(node) - case field: IField => + case Some(cppVariable: CPPVariable) => + val name = shortName(funcDecl) + val tpe = cleanType(safeGetType(cppVariable.getType)) + val codeString = code(funcDecl.getParent) + val node = localNode(funcDecl, name, codeString, registerType(tpe)) + scope.addToScope(name, (node, tpe)) + Ast(node) + case Some(field: IField) => // TODO create a member for the field // We get here a least for function pointer member declarations in classes like: // class A { @@ -180,10 +188,10 @@ trait AstForFunctionsCreator(implicit withSchemaValidation: ValidationMode) { th // void (*foo)(int); // }; Ast() - case typeDef: ITypedef => + case Some(typeDef: ITypedef) => // TODO handle typeDecl for now we just ignore this. Ast() - case other => + case _ => notHandledYet(funcDecl) } diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForPrimitivesCreator.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForPrimitivesCreator.scala index 5ce7f415c2df..e76b71627a33 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForPrimitivesCreator.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForPrimitivesCreator.scala @@ -62,17 +62,16 @@ trait AstForPrimitivesCreator(implicit withSchemaValidation: ValidationMode) { t private def maybeMethodRefForIdentifier(ident: IASTNode): Option[NewMethodRef] = { ident match { case id: IASTIdExpression if id.getName != null => - id.getName.resolveBinding() - val (mayBeFullName, mayBeTypeFullName) = id.getName.getBinding match { - case binding: ICInternalBinding if binding.getDefinition.isInstanceOf[IASTFunctionDeclarator] => + val (mayBeFullName, mayBeTypeFullName) = safeGetBinding(id) match { + case Some(binding: ICInternalBinding) if binding.getDefinition.isInstanceOf[IASTFunctionDeclarator] => namesForBinding(binding) - case binding: ICInternalBinding + case Some(binding: ICInternalBinding) if binding.getDeclarations != null && binding.getDeclarations.exists(_.isInstanceOf[IASTFunctionDeclarator]) => namesForBinding(binding) - case binding: ICPPInternalBinding if binding.getDefinition.isInstanceOf[IASTFunctionDeclarator] => + case Some(binding: ICPPInternalBinding) if binding.getDefinition.isInstanceOf[IASTFunctionDeclarator] => namesForBinding(binding) - case binding: ICPPInternalBinding + case Some(binding: ICPPInternalBinding) if binding.getDeclarations != null && binding.getDeclarations.exists(_.isInstanceOf[CPPASTFunctionDeclarator]) => namesForBinding(binding) @@ -102,7 +101,7 @@ trait AstForPrimitivesCreator(implicit withSchemaValidation: ValidationMode) { t case id: IASTIdExpression => ASTStringUtil.getSimpleName(id.getName) case id: IASTName => val name = ASTStringUtil.getSimpleName(id) - if (name.isEmpty) Try(id.resolveBinding().getName).getOrElse(uniqueName("name", "", "")._1) + if (name.isEmpty) safeGetBinding(id).map(_.getName).getOrElse(uniqueName("name", "", "")._1) else name case _ => code(ident) } @@ -110,7 +109,7 @@ trait AstForPrimitivesCreator(implicit withSchemaValidation: ValidationMode) { t private def syntheticThisAccess(ident: CPPASTIdExpression, identifierName: String): String | Ast = { val tpe = ident.getName.getBinding match { - case f: CPPField => f.getType.toString + case f: CPPField => safeGetType(f.getType) case _ => typeFor(ident) } Try(ident.getEvaluation).toOption match { diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala index 7964fdca5bcb..2cfb3240c12b 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala @@ -24,8 +24,6 @@ import scala.collection.mutable trait AstForStatementsCreator(implicit withSchemaValidation: ValidationMode) { this: AstCreator => - import io.joern.c2cpg.astcreation.AstCreatorHelper.OptionSafeAst - protected def astForBlockStatement(blockStmt: IASTCompoundStatement, order: Int = -1): Ast = { val codeString = code(blockStmt) val blockCode = if (codeString == "{}" || codeString.isEmpty) Defines.Empty else codeString @@ -161,13 +159,15 @@ trait AstForStatementsCreator(implicit withSchemaValidation: ValidationMode) { t case alias: CPPASTNamespaceAlias => Seq(astForNamespaceAlias(alias)) case asm: IASTASMDeclaration => Seq(astForASMDeclaration(asm)) case _: ICPPASTUsingDirective => Seq.empty - case declaration => Seq(astForNode(declaration)) + case declaration => astsForDeclaration(declaration) } private def astForReturnStatement(ret: IASTReturnStatement): Ast = { val cpgReturn = returnNode(ret, code(ret)) - val expr = nullSafeAst(ret.getReturnValue) - Ast(cpgReturn).withChild(expr).withArgEdge(cpgReturn, expr.root) + nullSafeAst(ret.getReturnValue) match { + case retAst if retAst.root.isDefined => Ast(cpgReturn).withChild(retAst).withArgEdge(cpgReturn, retAst.root.get) + case _ => Ast(cpgReturn) + } } private def astForBreakStatement(br: IASTBreakStatement): Ast = { diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForTypesCreator.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForTypesCreator.scala index 6be1c982c293..e98dd2322da7 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForTypesCreator.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForTypesCreator.scala @@ -11,8 +11,6 @@ import org.eclipse.cdt.internal.core.model.ASTStringUtil import io.joern.x2cpg.datastructures.Stack.* import org.apache.commons.lang3.StringUtils -import scala.util.Try - trait AstForTypesCreator(implicit withSchemaValidation: ValidationMode) { this: AstCreator => private def parentIsClassDef(node: IASTNode): Boolean = Option(node.getParent) match { @@ -73,7 +71,7 @@ trait AstForTypesCreator(implicit withSchemaValidation: ValidationMode) { this: case d if isTypeDef(d) && shortName(d.getDeclSpecifier).nonEmpty => val filename = fileName(declaration) val typeDefName = if (name.isEmpty) { - Try(declarator.getName.resolveBinding()).toOption.map(b => registerType(b.getName)) + safeGetBinding(declarator.getName).map(b => registerType(b.getName)) } else { Option(registerType(name)) } @@ -233,7 +231,7 @@ trait AstForTypesCreator(implicit withSchemaValidation: ValidationMode) { this: case _ if declaration.getDeclarators.isEmpty => Seq(astForNode(declaration)) } case alias: CPPASTAliasDeclaration => Seq(astForAliasDeclaration(alias)) - case functDef: IASTFunctionDefinition => Seq(astForFunctionDefinition(functDef)) + case functionDefinition: IASTFunctionDefinition => Seq(astForFunctionDefinition(functionDefinition)) case namespaceAlias: ICPPASTNamespaceAlias => Seq(astForNamespaceAlias(namespaceAlias)) case namespaceDefinition: ICPPASTNamespaceDefinition => Seq(astForNamespaceDefinition(namespaceDefinition)) case a: ICPPASTStaticAssertDeclaration => Seq(astForStaticAssert(a)) diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/Defines.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/Defines.scala index 3bc3cddab365..c5f8d68554c7 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/Defines.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/Defines.scala @@ -19,6 +19,5 @@ object Defines { val OperatorCall = "()" val OperatorExpressionList = ".expressionList" val OperatorNew = ".new" - val OperatorThrow = ".throw" val OperatorBracketedPrimary = ".bracketedPrimary" } diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/FullNameProvider.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/FullNameProvider.scala index 558e0841d3c7..6d1e7832a34c 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/FullNameProvider.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/FullNameProvider.scala @@ -164,7 +164,7 @@ trait FullNameProvider { this: AstCreator => } private def returnTypeForIASTFunctionDeclarator(declarator: IASTFunctionDeclarator): String = { - Try(declarator.getName.resolveBinding()).toOption match { + safeGetBinding(declarator.getName) match { case Some(value: ICPPMethod) => cleanType(value.getType.getReturnType.toString) case _ => @@ -176,7 +176,7 @@ trait FullNameProvider { this: AstCreator => if (isCppConstructor(definition)) { typeFor(definition.asInstanceOf[CPPASTFunctionDefinition].getMemberInitializers.head.getInitializer) } else { - Try(definition.getDeclarator.getName.resolveBinding()).toOption match { + safeGetBinding(definition.getDeclarator.getName) match { case Some(value: ICPPMethod) => cleanType(value.getType.getReturnType.toString) case _ => @@ -221,7 +221,7 @@ trait FullNameProvider { this: AstCreator => } private def shortNameForIASTDeclarator(declarator: IASTDeclarator): String = { - Try(declarator.getName.resolveBinding().getName).getOrElse { + safeGetBinding(declarator.getName).map(_.getName).getOrElse { if (ASTStringUtil.getSimpleName(declarator.getName).isEmpty && declarator.getNestedDeclarator != null) { shortName(declarator.getNestedDeclarator) } else { @@ -294,8 +294,8 @@ trait FullNameProvider { this: AstCreator => case _ => None } case declarator: CPPASTFunctionDeclarator => - declarator.getName.resolveBinding() match { - case function: ICPPFunction if declarator.getName.isInstanceOf[ICPPASTConversionName] => + safeGetBinding(declarator.getName) match { + case Some(function: ICPPFunction) if declarator.getName.isInstanceOf[ICPPASTConversionName] => val tpe = cleanType(typeFor(declarator.getName.asInstanceOf[ICPPASTConversionName].getTypeId)) val fullNameNoSig = fixQualifiedName( function.getQualifiedName.takeWhile(!_.startsWith("operator ")).mkString(".") @@ -306,7 +306,7 @@ trait FullNameProvider { this: AstCreator => s"$fullNameNoSig.$tpe:${functionTypeToSignature(function.getType)}" } Option(fn) - case function: ICPPFunction => + case Some(function: ICPPFunction) => val fullNameNoSig = fixQualifiedName(replaceOperator(function.getQualifiedName.mkString("."))) val fn = if (function.isExternC) { replaceOperator(function.getName) @@ -319,7 +319,7 @@ trait FullNameProvider { this: AstCreator => s"$fullNameNoSig:$sig" } Option(fn) - case x @ (_: ICPPField | _: CPPVariable) => + case Some(x @ (_: ICPPField | _: CPPVariable)) => val fullNameNoSig = fixQualifiedName(x.getQualifiedName.mkString(".")) val fn = if (x.isExternC) { x.getName @@ -327,7 +327,7 @@ trait FullNameProvider { this: AstCreator => s"$fullNameNoSig:${cleanType(safeGetType(x.getType))}" } Option(fn) - case _: IProblemBinding => + case Some(_: IProblemBinding) => val fullNameNoSig = replaceOperator(ASTStringUtil.getQualifiedName(declarator.getName)) val fixedFullName = fixQualifiedName(fullNameNoSig) if (fixedFullName.isEmpty) { @@ -338,31 +338,32 @@ trait FullNameProvider { this: AstCreator => case _ => None } case declarator: CASTFunctionDeclarator => - declarator.getName.resolveBinding() match { - case cVariable: CVariable => Option(cVariable.getName) - case _ => Option(declarator.getName.toString) + safeGetBinding(declarator.getName) match { + case Some(cVariable: CVariable) => Option(cVariable.getName) + case Some(cppVariable: CPPVariable) => Option(cppVariable.getName) + case _ => Option(declarator.getName.toString) } case definition: ICPPASTFunctionDefinition => Some(fullName(definition.getDeclarator)) case namespace: ICPPASTNamespaceDefinition => - namespace.getName.resolveBinding() match { - case b: ICPPBinding if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) - case _ => None + safeGetBinding(namespace.getName) match { + case Some(b: ICPPBinding) if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) + case _ => None } case compType: IASTCompositeTypeSpecifier => - compType.getName.resolveBinding() match { - case b: ICPPBinding if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) - case _ => None + safeGetBinding(compType.getName) match { + case Some(b: ICPPBinding) if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) + case _ => None } case enumSpecifier: IASTEnumerationSpecifier => - enumSpecifier.getName.resolveBinding() match { - case b: ICPPBinding if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) - case _ => None + safeGetBinding(enumSpecifier.getName) match { + case Some(b: ICPPBinding) if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) + case _ => None } case e: IASTElaboratedTypeSpecifier => - e.getName.resolveBinding() match { - case b: ICPPBinding if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) - case _ => None + safeGetBinding(e.getName) match { + case Some(b: ICPPBinding) if b.getName.nonEmpty => Option(b.getQualifiedName.mkString(".")) + case _ => None } case _ => None } diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/MacroArgumentExtractor.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/MacroArgumentExtractor.scala index c6ae64535fea..76e5aa4ba5c3 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/MacroArgumentExtractor.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/MacroArgumentExtractor.scala @@ -26,8 +26,6 @@ import scala.collection.mutable * `setExpandedMacroArgument`, we can intercept arguments and store them in a list for later retrieval. We wrap this * rather complicated way of accessing the macro arguments in the single public method `getArguments` of the * `MacroArgumentExtractor`. - * - * This class must be in this package in order to have access to `PreprocessorMacro`. */ class MacroArgumentExtractor(tu: IASTTranslationUnit, loc: IASTFileLocation) {