Skip to content

Commit

Permalink
Fix bug in debug info for lambdas (#637)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer authored Aug 17, 2024
1 parent 59392c0 commit 433de2f
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 22 deletions.
9 changes: 3 additions & 6 deletions src/irgenerator/DebugInfoGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ void DebugInfoGenerator::initialize(const std::string &sourceFileName, std::file
nullptr, "_fat_ptr");

llvm::DIType *voidPtrDIType = diBuilder->createPointerType(voidTy, pointerWidth, ptrAlignInBits);
llvm::DIDerivedType *firstType = diBuilder->createMemberType(fatPtrTy, "first", diFile, 0, pointerWidth, ptrAlignInBits, 0,
llvm::DIDerivedType *firstType = diBuilder->createMemberType(fatPtrTy, "fct", diFile, 0, pointerWidth, ptrAlignInBits, 0,
llvm::DINode::FlagZero, voidPtrDIType);
llvm::DIDerivedType *secondType = diBuilder->createMemberType(fatPtrTy, "second", diFile, 0, pointerWidth, ptrAlignInBits,
llvm::DIDerivedType *secondType = diBuilder->createMemberType(fatPtrTy, "captures", diFile, 0, pointerWidth, ptrAlignInBits,
pointerWidth, llvm::DINode::FlagZero, voidPtrDIType);
fatPtrTy->replaceElements(llvm::MDTuple::get(context, {firstType, secondType}));
}
Expand Down Expand Up @@ -151,7 +151,6 @@ void DebugInfoGenerator::concludeFunctionDebugInfo() {

assert(!lexicalBlocks.empty());
lexicalBlocks.pop();
assert(lexicalBlocks.empty());
}

void DebugInfoGenerator::pushLexicalBlock(const ASTNode *node) {
Expand Down Expand Up @@ -272,9 +271,7 @@ void DebugInfoGenerator::setSourceLocation(const CodeLoc &codeLoc) {
irGenerator->builder.SetCurrentDebugLocation(diCodeLoc);
}

void DebugInfoGenerator::setSourceLocation(const ASTNode *node) {
setSourceLocation(node->codeLoc);
}
void DebugInfoGenerator::setSourceLocation(const ASTNode *node) { setSourceLocation(node->codeLoc); }

void DebugInfoGenerator::finalize() const {
if (irGenerator->cliOptions.generateDebugInfo)
Expand Down
2 changes: 2 additions & 0 deletions src/irgenerator/GenTargetDependent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const char *IRGenerator::getSysCallAsmString() const {
"syscall\n";

assert_fail("Unsupported target for inline assembly");
return nullptr;
}

const char *IRGenerator::getSysCallConstraintString() const {
Expand All @@ -48,6 +49,7 @@ const char *IRGenerator::getSysCallConstraintString() const {
if (cliOptions.targetArch == "aarch64" || cliOptions.targetArch == "arm64")
return "r,r,r,r,r,r,r,~{x8},~{x0},~{x1},~{x2},~{x3},~{x4},~{x5},~{dirflag},~{fpsr},~{flags}";
assert_fail("Unsupported target for inline assembly");
return nullptr;
}

} // namespace spice::compiler
18 changes: 12 additions & 6 deletions src/irgenerator/GenValues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,14 +509,16 @@ std::any IRGenerator::visitLambdaFunc(const LambdaFuncNode *node) {
llvm::Type *paramType = funcType->getParamType(argNumber);
llvm::Value *paramAddress = insertAlloca(paramType, paramName);
// Update the symbol table entry
if (hasCaptures && argNumber == 0)
const bool isCapturesStruct = hasCaptures && argNumber == 0;
if (isCapturesStruct)
captureStructPtrPtr = paramAddress;
else
paramSymbol->updateAddress(paramAddress);
// Store the value at the new address
insertStore(&arg, paramAddress);
// Generate debug info
diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1);
if (!isCapturesStruct)
diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1);
}

// Store the default values for optional function args
Expand Down Expand Up @@ -652,14 +654,16 @@ std::any IRGenerator::visitLambdaProc(const LambdaProcNode *node) {
llvm::Type *paramType = funcType->getParamType(argNumber);
llvm::Value *paramAddress = insertAlloca(paramType, paramName);
// Update the symbol table entry
if (hasCaptures && argNumber == 0)
const bool isCapturesStruct = hasCaptures && argNumber == 0;
if (isCapturesStruct)
captureStructPtrPtr = paramAddress;
else
paramSymbol->updateAddress(paramAddress);
// Store the value at the new address
insertStore(&arg, paramAddress);
// Generate debug info
diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1);
if (!isCapturesStruct)
diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1);
}

// Store the default values for optional function args
Expand Down Expand Up @@ -797,14 +801,16 @@ std::any IRGenerator::visitLambdaExpr(const LambdaExprNode *node) {
llvm::Type *paramType = funcType->getParamType(argNumber);
llvm::Value *paramAddress = insertAlloca(paramType, paramName);
// Update the symbol table entry
if (hasCaptures && argNumber == 0)
const bool isCapturesStruct = hasCaptures && argNumber == 0;
if (isCapturesStruct)
captureStructPtrPtr = paramAddress;
else
paramSymbol->updateAddress(paramAddress);
// Store the value at the new address
insertStore(&arg, paramAddress);
// Generate debug info
diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1);
if (!isCapturesStruct)
diGenerator.generateLocalVarDebugInfo(paramName, paramAddress, argNumber + 1);
}

// Store the default values for optional function args
Expand Down
2 changes: 1 addition & 1 deletion src/symboltablebuilder/TypeChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void TypeChainElement::getName(std::stringstream &name, bool withSize) const {
name << "&";
break;
case TY_ARRAY:
name << (withSize && data.arraySize != ARRAY_SIZE_UNKNOWN ? "[" + std::to_string(data.arraySize) + "]" : "");
name << "[" << (withSize && data.arraySize != ARRAY_SIZE_UNKNOWN ? std::to_string(data.arraySize) : "") << "]";
break;
case TY_DOUBLE:
name << "double";
Expand Down
13 changes: 7 additions & 6 deletions src/typechecker/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ std::any TypeChecker::visitEntry(EntryNode *node) {

// Check which implicit structures we need for each struct, defined in this source file
if (isPrepare) {
for (const Struct *manifestation : rootScope->getAllStructManifestationsInDeclarationOrder()) {
const std::vector<const Struct *> manifestations = rootScope->getAllStructManifestationsInDeclarationOrder();
for (const Struct *manifestation : manifestations) {
// Check if we need to create a default ctor, copy ctor or dtor
createDefaultCtorIfRequired(*manifestation, manifestation->scope);
createDefaultCopyCtorIfRequired(*manifestation, manifestation->scope);
Expand Down Expand Up @@ -1241,20 +1242,20 @@ std::any TypeChecker::visitCastExpr(CastExprNode *node) {
return visit(node->prefixUnaryExpr());

// Visit source type
auto src = std::any_cast<ExprResult>(visit(node->prefixUnaryExpr()));
const auto src = std::any_cast<ExprResult>(visit(node->prefixUnaryExpr()));
HANDLE_UNRESOLVED_TYPE_ER(src.type)
// Visit destination type
auto dstType = std::any_cast<QualType>(visit(node->dataType()));
const auto dstType = std::any_cast<QualType>(visit(node->dataType()));
HANDLE_UNRESOLVED_TYPE_ER(dstType)

// Check for identity cast
if (src.type == dstType) {
CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified.");
const CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified.");
sourceFile->compilerOutput.warnings.push_back(warning);
}

// Get result type
QualType resultType = opRuleManager.getCastResultType(node, dstType, src);
const QualType resultType = opRuleManager.getCastResultType(node, dstType, src);

SymbolTableEntry *entry = src.type.isSameContainerTypeAs(dstType) ? src.entry : nullptr;
return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry};
Expand Down Expand Up @@ -2344,7 +2345,7 @@ std::any TypeChecker::visitDataType(DataTypeNode *node) {
type.getSpecifiers().isUnsigned = true;
} else if (specifier->type == SpecifierNode::TY_HEAP) {
// Heap variables can only be pointers
if (!type.removeReferenceWrapper().isOneOf({TY_PTR, TY_STRING}))
if (!type.removeReferenceWrapper().isOneOf({TY_PTR, TY_ARRAY, TY_STRING}))
SOFT_ERROR_QT(specifier, SPECIFIER_AT_ILLEGAL_CONTEXT,
"The heap specifier can only be applied to symbols of pointer type, you provided " +
baseType.getName(false))
Expand Down
2 changes: 1 addition & 1 deletion src/typechecker/TypeCheckerImplicit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void TypeChecker::createDefaultCopyCtorIfRequired(const Struct &spiceStruct, Sco
if (copyCtor != nullptr)
return;

// Abort if the struct has a user-defiend move constructor
// Abort if the struct has a user-defined move constructor
// ToDo: Check for move ctor

// Check if we have fields, that require us to do anything in the ctor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ Pthread_attr_t&
Pthread_attr_t*
Pthread_t
Thread
Thread
Thread&
Thread*
Thread[]
bool
byte
byte*
byte**
char
char*
dyn
dyn
dyn[]
f()
f<int>()
f<int>(int)
Expand Down

0 comments on commit 433de2f

Please sign in to comment.