Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixes for declarations #179

Merged
merged 17 commits into from
Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import de.fraunhofer.aisec.cpg.graph.TranslationUnitDeclaration;
import de.fraunhofer.aisec.cpg.graph.TypeManager;
import de.fraunhofer.aisec.cpg.graph.ValueDeclaration;
import de.fraunhofer.aisec.cpg.graph.type.Type;
import de.fraunhofer.aisec.cpg.graph.type.TypeParser;
import de.fraunhofer.aisec.cpg.graph.type.UnknownType;
import de.fraunhofer.aisec.cpg.helpers.Benchmark;
Expand Down Expand Up @@ -87,13 +86,6 @@
*/
public class CXXLanguageFrontend extends LanguageFrontend {

public static final Type LONG_TYPE = TypeParser.createFrom("long", true);
public static final Type TYPE_UNSIGNED_LONG_LONG =
TypeParser.createFrom("unsigned long long", true);
public static final Type INT_TYPE = TypeParser.createFrom("int", true);
public static final Type LONG_LONG_TYPE = TypeParser.createFrom("long long", true);
public static final Type TYPE_UNSIGNED_LONG = TypeParser.createFrom("unsigned long", true);

private static final Logger LOGGER = LoggerFactory.getLogger(CXXLanguageFrontend.class);
private final IncludeFileContentProvider includeFileContentProvider =
new InternalFileContentProvider() {
Expand Down Expand Up @@ -188,7 +180,6 @@ public InternalFileContent getContentForInclusion(IIndexFileLocation ifl, String
}
};
private DeclarationHandler declarationHandler = new DeclarationHandler(this);
private DeclarationListHandler declarationListHandler = new DeclarationListHandler(this);
private DeclaratorHandler declaratorHandler = new DeclaratorHandler(this);
private ExpressionHandler expressionHandler = new ExpressionHandler(this);
private InitializerHandler initializerHandler = new InitializerHandler(this);
Expand Down Expand Up @@ -432,7 +423,7 @@ private Expression handleToken(IASTToken token) {
case 1:
return newDeclaredReferenceExpression(code, UnknownType.getUnknownType(), code);
case 2:
return newLiteral(Integer.parseInt(code), CXXLanguageFrontend.INT_TYPE, code);
return newLiteral(Integer.parseInt(code), TypeParser.createFrom("int", true), code);
case 130:
return newLiteral(
code.length() >= 2 ? code.substring(1, code.length() - 1) : "",
Expand Down Expand Up @@ -570,10 +561,6 @@ public DeclarationHandler getDeclarationHandler() {
return declarationHandler;
}

public DeclarationListHandler getDeclarationListHandler() {
return declarationListHandler;
}

public DeclaratorHandler getDeclaratorHandler() {
return declaratorHandler;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,27 @@
package de.fraunhofer.aisec.cpg.frontends.cpp;

import static de.fraunhofer.aisec.cpg.helpers.Util.errorWithFileLocation;
import static de.fraunhofer.aisec.cpg.helpers.Util.warnWithFileLocation;

import de.fraunhofer.aisec.cpg.frontends.Handler;
import de.fraunhofer.aisec.cpg.graph.*;
import de.fraunhofer.aisec.cpg.graph.CompoundStatement;
import de.fraunhofer.aisec.cpg.graph.ConstructorDeclaration;
import de.fraunhofer.aisec.cpg.graph.Declaration;
import de.fraunhofer.aisec.cpg.graph.DeclarationSequence;
import de.fraunhofer.aisec.cpg.graph.FunctionDeclaration;
import de.fraunhofer.aisec.cpg.graph.IncludeDeclaration;
import de.fraunhofer.aisec.cpg.graph.MethodDeclaration;
import de.fraunhofer.aisec.cpg.graph.NamespaceDeclaration;
import de.fraunhofer.aisec.cpg.graph.NodeBuilder;
import de.fraunhofer.aisec.cpg.graph.ProblemDeclaration;
import de.fraunhofer.aisec.cpg.graph.RecordDeclaration;
import de.fraunhofer.aisec.cpg.graph.ReturnStatement;
import de.fraunhofer.aisec.cpg.graph.Statement;
import de.fraunhofer.aisec.cpg.graph.TranslationUnitDeclaration;
import de.fraunhofer.aisec.cpg.graph.TypeManager;
import de.fraunhofer.aisec.cpg.graph.ValueDeclaration;
import de.fraunhofer.aisec.cpg.graph.VariableDeclaration;
import de.fraunhofer.aisec.cpg.graph.type.Type;
import de.fraunhofer.aisec.cpg.graph.type.TypeParser;
import de.fraunhofer.aisec.cpg.helpers.Util;
import java.util.HashMap;
Expand All @@ -46,13 +63,26 @@
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.*;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLinkageSpecification;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTProblemDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUsingDirective;

public class DeclarationHandler extends Handler<Declaration, IASTDeclaration, CXXLanguageFrontend> {

public DeclarationHandler(CXXLanguageFrontend lang) {
super(Declaration::new, lang);

map.put(
CPPASTTemplateDeclaration.class,
ctx -> handleTemplateDeclaration((CPPASTTemplateDeclaration) ctx));
map.put(
CPPASTSimpleDeclaration.class,
ctx -> handleSimpleDeclaration((CPPASTSimpleDeclaration) ctx));
Expand Down Expand Up @@ -102,6 +132,7 @@ private Declaration handleProblem(CPPASTProblemDeclaration ctx) {
private FunctionDeclaration handleFunctionDefinition(CPPASTFunctionDefinition ctx) {
// Todo: A problem with cpp functions is that we cannot know if they may throw an exception as
// throw(...) is not compiler enforced (Problem for TryStatement)

FunctionDeclaration functionDeclaration =
(FunctionDeclaration) this.lang.getDeclaratorHandler().handle(ctx.getDeclarator());

Expand All @@ -111,12 +142,17 @@ private FunctionDeclaration handleFunctionDefinition(CPPASTFunctionDefinition ct

// It is a constructor
if (functionDeclaration instanceof MethodDeclaration && typeString.isEmpty()) {
functionDeclaration = ConstructorDeclaration.from((MethodDeclaration) functionDeclaration);
ConstructorDeclaration constructorDeclaration =
ConstructorDeclaration.from((MethodDeclaration) functionDeclaration);

// update our scope manager, otherwise scopes will still point to our old non-existing
// function declaration
this.lang.getScopeManager().replaceNode(constructorDeclaration, functionDeclaration);

functionDeclaration = constructorDeclaration;
}

functionDeclaration.setType(
TypeParser.createFrom(
ctx.getRawSignature().split(functionDeclaration.getName())[0].trim(), true));
functionDeclaration.setType(TypeParser.createFrom(typeString, true));

// associated record declaration if this is a method or constructor
RecordDeclaration recordDeclaration =
Expand Down Expand Up @@ -213,71 +249,35 @@ private boolean isTypedef(CPPASTSimpleDeclaration ctx) {
}
}

private Declaration handleSimpleDeclaration(CPPASTSimpleDeclaration ctx) {
if (isTypedef(ctx)) {
TypeManager.getInstance().handleTypedef(ctx.getRawSignature());
// if this was a struct typedef, we still need to handle this struct!
if (!(ctx.getDeclSpecifier() instanceof CPPASTCompositeTypeSpecifier)) {
return null;
}
}
private Declaration handleTemplateDeclaration(CPPASTTemplateDeclaration ctx) {
warnWithFileLocation(
lang,
ctx,
log,
"Parsing template declarations is not supported (yet). Will ignore template and parse inner declaration");

Declaration declaration;
if (ctx.getDeclarators().length == 0) {
declaration = handleNoDeclarator(ctx);
} else if (ctx.getDeclarators().length == 1) {
declaration = handleSingleDeclarator(ctx);
} else {
declaration = handleMultipleDeclarators(ctx);
}

if (declaration != null) {
this.lang.processAttributes(declaration, ctx);
}

return declaration;
return handle(ctx.getDeclaration());
}

private Declaration handleNoDeclarator(CPPASTSimpleDeclaration ctx) {
if (ctx.getDeclSpecifier() != null) {
if (ctx.getDeclSpecifier() instanceof CPPASTCompositeTypeSpecifier) {
// probably a class or struct declaration
return this.lang
.getDeclaratorHandler()
.handle((CPPASTCompositeTypeSpecifier) ctx.getDeclSpecifier());
} else {
errorWithFileLocation(
this.lang,
ctx,
log,
"Unknown DeclSpecifier in SimpleDeclaration: {}",
ctx.getDeclSpecifier().getClass());
}
} else {
errorWithFileLocation(this.lang, ctx, log, ("DeclSpecifier is null"));
private Declaration handleSimpleDeclaration(CPPASTSimpleDeclaration ctx) {
if (isTypedef(ctx)) {
TypeManager.getInstance().handleTypedef(ctx.getRawSignature());
}
return null;
}

private Declaration handleSingleDeclarator(CPPASTSimpleDeclaration ctx) {
List<Declaration> handle = (this.lang).getDeclarationListHandler().handle(ctx);
if (handle.size() != 1) {
errorWithFileLocation(this.lang, ctx, log, "Invalid declaration generation");
return NodeBuilder.newDeclaration("");
}
DeclarationSequence sequence = new DeclarationSequence();

return handle.get(0);
}
// check, whether the declaration specifier also contains declarations, i.e. class definitions
IASTDeclSpecifier declSpecifier = ctx.getDeclSpecifier();

private Declaration handleMultipleDeclarators(CPPASTSimpleDeclaration ctx) {
// A legitimate case where this will happen is when multiply typedefing a struct
// e.g.: typedef struct {...} S, *pS, s_arr[10], ...;
if (ctx.getDeclSpecifier() instanceof CPPASTCompositeTypeSpecifier) {
Declaration result =
if (declSpecifier instanceof CPPASTCompositeTypeSpecifier) {
Declaration declaration =
this.lang
.getDeclaratorHandler()
.handle((CPPASTCompositeTypeSpecifier) ctx.getDeclSpecifier());
if (result.getName().isEmpty() && ctx.getRawSignature().strip().startsWith("typedef")) {

// handle typedef
if ((declaration.getName().isEmpty()
&& ctx.getRawSignature().strip().startsWith("typedef"))) {
// CDT didn't find out the name due to this thing being a typedef. We need to fix this
int endOfDeclaration = ctx.getRawSignature().lastIndexOf('}');
if (endOfDeclaration + 1 < ctx.getRawSignature().length()) {
Expand All @@ -286,14 +286,52 @@ private Declaration handleMultipleDeclarators(CPPASTSimpleDeclaration ctx) {
ctx.getRawSignature().substring(endOfDeclaration + 1), ",");
Optional<String> name =
parts.stream().filter(p -> !p.contains("*") && !p.contains("[")).findFirst();
name.ifPresent(s -> result.setName(s.replace(";", "")));
name.ifPresent(s -> declaration.setName(s.replace(";", "")));
}
}
return result;

this.lang.processAttributes(declaration, ctx);

sequence.add(declaration);
} else if (declSpecifier instanceof CPPASTElaboratedTypeSpecifier) {
warnWithFileLocation(
lang,
ctx,
log,
"Parsing elaborated type specifiers is not supported (yet)",
declSpecifier.getClass());
}

for (IASTDeclarator declarator : ctx.getDeclarators()) {
ValueDeclaration declaration =
(ValueDeclaration) this.lang.getDeclaratorHandler().handle(declarator);

String typeString;
if (declaration instanceof FunctionDeclaration
|| declaration instanceof VariableDeclaration) {
typeString = getTypeStringFromDeclarator(declarator, ctx.getDeclSpecifier());
} else {
// otherwise, use the complete raw code and let the type parser handle it
typeString = ctx.getRawSignature();
}

Type result = TypeParser.createFrom(typeString, true);
declaration.setType(result);

// cache binding
this.lang.cacheDeclaration(declarator.getName().resolveBinding(), declaration);

// process attributes
this.lang.processAttributes(declaration, ctx);

sequence.add(declaration);
}

if (sequence.isSingle()) {
return sequence.first();
} else {
return sequence;
}
errorWithFileLocation(
this.lang, ctx, log, "More than one declaration, this should not happen here.");
return null;
}

private void parseInclusions(
Expand Down Expand Up @@ -338,8 +376,6 @@ TranslationUnitDeclaration handleTranslationUnit(CPPASTTranslationUnit translati
problematicIncludes.computeIfAbsent(
((ProblemDeclaration) decl).getFilename(), k -> new HashSet<>());
problems.add((ProblemDeclaration) decl);
} else if (decl instanceof NamespaceDeclaration) {
node.add(decl);
} else {
node.add(decl);
}
Expand Down

This file was deleted.

Loading