Skip to content

Commit

Permalink
Broaden use of QualType (#533)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer authored May 5, 2024
1 parent d9ca4c8 commit aa6ea56
Show file tree
Hide file tree
Showing 51 changed files with 928 additions and 877 deletions.
2 changes: 1 addition & 1 deletion .run/spice.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O0 -d -ir ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O0 -d ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<envs>
<env name="LLVM_ADDITIONAL_FLAGS" value="-lole32 -lws2_32" />
<env name="LLVM_BUILD_INCLUDE_DIR" value="$PROJECT_DIR$/../llvm-project-latest/build/include" />
Expand Down
22 changes: 11 additions & 11 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import "std/data/vector";
import "std/os/env";
import "bootstrap/lexer/lexer";

f<int> main() {
Vector<int> intVector;
intVector.pushBack(1);
intVector.pushBack(5);
intVector.pushBack(4);
intVector.pushBack(0);
intVector.pushBack(12);
intVector.pushBack(12345);
intVector.pushBack(9);
foreach const int item : intVector {
printf("Item: %d\n", item);
String filePath = getEnv("SPICE_STD_DIR") + "/../test/test-files/bootstrap-compiler/standalone-lexer-test/test-file.spice";
Lexer lexer = Lexer(filePath.getRaw());
unsigned long tokenCount = 0l;
while (!lexer.isEOF()) {
Token token = lexer.getToken();
token.print();
lexer.advance();
tokenCount++;
}
printf("\nLexed tokens: %d\n", tokenCount);
}

/*import "bootstrap/util/block-allocator";
Expand Down
2 changes: 1 addition & 1 deletion src-bootstrap/ast/ast-nodes.spice
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "std/data/vector";
// Own imports
//import "../ast/abstract-ast-visitor";
import "../reader/code-loc";
//import "../symboltablebuilder/symbol-type";
//import "../symboltablebuilder/type";

/**
* Saves a constant value for an AST node to realize features like array-out-of-bounds checks
Expand Down
5 changes: 5 additions & 0 deletions src-bootstrap/symboltablebuilder/qual-type.spice
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


public type QualType struct {

}
2 changes: 1 addition & 1 deletion src-bootstrap/symboltablebuilder/symbol-table.spice
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "std/data/vector";

// Own imports
import "../ast/ast-nodes";
import "../symboltablebuilder/symbol-type";
import "../symboltablebuilder/type";
import "../symboltablebuilder/symbol-table-entry";
import "../symboltablebuilder/type-specifiers";
import "../model/capture";
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/ast/ASTNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1916,7 +1916,7 @@ class FctCallNode : public ExprNode {
// Methods
[[nodiscard]] bool isOrdinaryCall() const { return callType == TYPE_ORDINARY; }
[[nodiscard]] bool isMethodCall() const { return callType == TYPE_METHOD; }
[[nodiscard]] bool isVirtualMethodCall() const { return isMethodCall() && thisType.isBaseType(TY_INTERFACE); }
[[nodiscard]] bool isVirtualMethodCall() const { return isMethodCall() && thisType.isBase(TY_INTERFACE); }
[[nodiscard]] bool isCtorCall() const { return callType == TYPE_CTOR; }
[[nodiscard]] bool isFctPtrCall() const { return callType == TYPE_FCT_PTR; }
};
Expand Down
78 changes: 39 additions & 39 deletions src/irgenerator/DebugInfoGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void DebugInfoGenerator::generateFunctionDebugInfo(llvm::Function *llvmFunction,
// Prepare flags
llvm::DIScope *scope = diFile;
llvm::DINode::DIFlags flags = llvm::DINode::FlagPrototyped;
if (spiceFunc->entry && spiceFunc->entry->getType().specifiers.isPublic)
if (spiceFunc->entry && spiceFunc->entry->getQualType().isPublic())
flags |= llvm::DINode::FlagPublic;

// Prepare spFlags
Expand All @@ -111,17 +111,17 @@ void DebugInfoGenerator::generateFunctionDebugInfo(llvm::Function *llvmFunction,
if (spiceFunc->isProcedure())
argTypes.push_back(voidTy);
else
argTypes.push_back(getDITypeForSymbolType(node, spiceFunc->returnType)); // Add result type
argTypes.push_back(getDITypeForQualType(node, spiceFunc->returnType)); // Add result type
if (spiceFunc->isMethod())
argTypes.push_back(getDITypeForSymbolType(node, spiceFunc->thisType)); // Add this type
argTypes.push_back(getDITypeForQualType(node, spiceFunc->thisType)); // Add this type
if (isLambda) {
llvm::DICompositeType *captureStructType = generateCaptureStructDebugInfo(spiceFunc);
scope = captureStructType;
llvm::DIType *captureStructPtr = diBuilder->createPointerType(captureStructType, pointerWidth);
argTypes.push_back(captureStructPtr); // Add this type
}
for (const Type &argType : spiceFunc->getParamTypes()) // Add arg types
argTypes.push_back(getDITypeForSymbolType(node, argType));
for (const QualType &argType : spiceFunc->getParamTypes()) // Add arg types
argTypes.push_back(getDITypeForQualType(node, argType));

// Create function type
llvm::DISubroutineType *functionTy = diBuilder->createSubroutineType(diBuilder->getOrCreateTypeArray(argTypes));
Expand Down Expand Up @@ -176,17 +176,17 @@ llvm::DICompositeType *DebugInfoGenerator::generateCaptureStructDebugInfo(const
// Get LLVM type for struct
std::vector<llvm::Type *> fieldTypes;
std::vector<SymbolTableEntry *> fieldEntries;
std::vector<Type> fieldSymbolTypes;
std::vector<QualType> fieldSymbolTypes;
for (const auto &[_, capture] : captures) {
Type captureType = capture.capturedEntry->getType();
QualType captureType = capture.capturedEntry->getQualType();

// Capture by reference
if (capture.getMode() == BY_REFERENCE)
captureType = captureType.toReference(node);
captureType = captureType.toRef(node);

fieldEntries.push_back(capture.capturedEntry);
fieldSymbolTypes.push_back(captureType);
fieldTypes.push_back(captureType.toLLVMType(irGenerator->context, irGenerator->currentScope));
fieldTypes.push_back(captureType.getType().toLLVMType(irGenerator->context, irGenerator->currentScope));
}
llvm::StructType *structType = llvm::StructType::get(irGenerator->context, fieldTypes, CAPTURES_PARAM_NAME);
const llvm::StructLayout *structLayout = irGenerator->module->getDataLayout().getStructLayout(structType);
Expand All @@ -199,7 +199,7 @@ llvm::DICompositeType *DebugInfoGenerator::generateCaptureStructDebugInfo(const

std::vector<llvm::Metadata *> fieldDITypes;
for (size_t i = 0; i < fieldEntries.size(); i++) {
llvm::DIType *fieldDiType = getDITypeForSymbolType(node, fieldSymbolTypes.at(i));
llvm::DIType *fieldDiType = getDITypeForQualType(node, fieldSymbolTypes.at(i));
const std::string &fieldName = fieldEntries.at(i)->name;
const size_t offsetInBits = structLayout->getElementOffsetInBits(i);
const size_t fieldSize = fieldDiType->getSizeInBits();
Expand All @@ -219,8 +219,8 @@ void DebugInfoGenerator::generateGlobalVarDebugInfo(llvm::GlobalVariable *global

const size_t lineNo = globalEntry->getDeclCodeLoc().line;
llvm::StringRef name = global->getName();
llvm::DIType *type = getDITypeForSymbolType(globalEntry->declNode, globalEntry->getType());
const bool isLocal = globalEntry->getType().isPublic();
llvm::DIType *type = getDITypeForQualType(globalEntry->declNode, globalEntry->getQualType());
const bool isLocal = globalEntry->getQualType().isPublic();

global->addDebugInfo(diBuilder->createGlobalVariableExpression(compileUnit, name, name, diFile, lineNo, type, isLocal));
}
Expand All @@ -244,7 +244,7 @@ void DebugInfoGenerator::generateLocalVarDebugInfo(const std::string &varName, l
assert(variableEntry != nullptr);
// Build debug info
llvm::DIScope *scope = lexicalBlocks.top();
llvm::DIType *diType = getDITypeForSymbolType(variableEntry->declNode, variableEntry->getType());
llvm::DIType *diType = getDITypeForQualType(variableEntry->declNode, variableEntry->getQualType());
const size_t lineNo = variableEntry->declNode->codeLoc.line;

llvm::DILocalVariable *varInfo;
Expand Down Expand Up @@ -275,41 +275,41 @@ void DebugInfoGenerator::finalize() {
diBuilder->finalize();
}

llvm::DIType *DebugInfoGenerator::getDITypeForSymbolType(const ASTNode *node, const Type &symbolType) const {
// Pointer type
if (symbolType.isPtr()) {
llvm::DIType *pointeeTy = getDITypeForSymbolType(node, symbolType.getContainedTy());
llvm::DIType *DebugInfoGenerator::getDITypeForQualType(const ASTNode *node, const QualType &ty) const { // NOLINT(*-no-recursion)
// Pointer ty
if (ty.isPtr()) {
llvm::DIType *pointeeTy = getDITypeForQualType(node, ty.getContained());
return diBuilder->createPointerType(pointeeTy, pointerWidth);
}

// Reference type
if (symbolType.isRef()) {
llvm::DIType *referencedType = getDITypeForSymbolType(node, symbolType.getContainedTy());
// Reference ty
if (ty.isRef()) {
llvm::DIType *referencedType = getDITypeForQualType(node, ty.getContained());
return diBuilder->createReferenceType(llvm::dwarf::DW_TAG_reference_type, referencedType, pointerWidth);
}

// Array type
if (symbolType.isArray()) {
llvm::DIType *itemTy = getDITypeForSymbolType(node, symbolType.getContainedTy());
const size_t size = symbolType.getArraySize();
// Array ty
if (ty.isArray()) {
llvm::DIType *itemTy = getDITypeForQualType(node, ty.getContained());
const size_t size = ty.getType().getArraySize();
llvm::DINodeArray subscripts = diBuilder->getOrCreateArray({});
return diBuilder->createArrayType(size, 0, itemTy, subscripts);
}

// Primitive types
llvm::DIType *baseDiType;
switch (symbolType.getSuperType()) {
switch (ty.getSuperType()) {
case TY_DOUBLE:
baseDiType = doubleTy;
break;
case TY_INT:
baseDiType = symbolType.isSigned() ? intTy : uIntTy;
baseDiType = ty.isSigned() ? intTy : uIntTy;
break;
case TY_SHORT:
baseDiType = symbolType.isSigned() ? shortTy : uShortTy;
baseDiType = ty.isSigned() ? shortTy : uShortTy;
break;
case TY_LONG:
baseDiType = symbolType.isSigned() ? longTy : uLongTy;
baseDiType = ty.isSigned() ? longTy : uLongTy;
break;
case TY_BYTE:
baseDiType = byteTy;
Expand All @@ -324,24 +324,24 @@ llvm::DIType *DebugInfoGenerator::getDITypeForSymbolType(const ASTNode *node, co
baseDiType = boolTy;
break;
case TY_STRUCT: {
Struct *spiceStruct = symbolType.getStruct(node);
Struct *spiceStruct = ty.getType().getStruct(node);
assert(spiceStruct != nullptr);

// Check if we already know the DI type
// Check if we already know the DI ty
if (spiceStruct->diType != nullptr) {
baseDiType = spiceStruct->diType;
break;
}

// Retrieve information about the struct
const size_t lineNo = spiceStruct->getDeclCodeLoc().line;
llvm::Type *structType = spiceStruct->entry->getType().toLLVMType(irGenerator->context, irGenerator->currentScope);
llvm::Type *structType = spiceStruct->entry->getQualType().toLLVMType(irGenerator->context, irGenerator->currentScope);
assert(structType != nullptr);
llvm::DataLayout dataLayout = irGenerator->module->getDataLayout();
const llvm::StructLayout *structLayout = dataLayout.getStructLayout(reinterpret_cast<llvm::StructType *>(structType));
const uint32_t alignInBits = dataLayout.getABITypeAlign(structType).value();

// Create struct type
// Create struct ty
const std::string mangledName = NameMangling::mangleStruct(*spiceStruct);
llvm::DICompositeType *structDiType = diBuilder->createStructType(
diFile, spiceStruct->name, diFile, lineNo, structLayout->getSizeInBits(), alignInBits,
Expand All @@ -357,11 +357,11 @@ llvm::DIType *DebugInfoGenerator::getDITypeForSymbolType(const ASTNode *node, co
if (fieldEntry->isImplicitField)
continue;

const Type fieldType = fieldEntry->getType();
const QualType &fieldType = fieldEntry->getQualType();
const size_t fieldLineNo = fieldEntry->declNode->codeLoc.line;
const size_t offsetInBits = structLayout->getElementOffsetInBits(i);

llvm::DIType *fieldDiType = getDITypeForSymbolType(node, fieldType);
llvm::DIType *fieldDiType = getDITypeForQualType(node, fieldType);
llvm::DIDerivedType *fieldDiDerivedType =
diBuilder->createMemberType(structDiType, fieldEntry->name, diFile, fieldLineNo, fieldDiType->getSizeInBits(),
fieldDiType->getAlignInBits(), offsetInBits, llvm::DINode::FlagZero, fieldDiType);
Expand All @@ -373,24 +373,24 @@ llvm::DIType *DebugInfoGenerator::getDITypeForSymbolType(const ASTNode *node, co
break;
}
case TY_INTERFACE: {
Interface *spiceInterface = symbolType.getInterface(node);
Interface *spiceInterface = ty.getType().getInterface(node);
assert(spiceInterface != nullptr);

// Check if we already know the DI type
// Check if we already know the DI ty
if (spiceInterface->diType != nullptr) {
baseDiType = spiceInterface->diType;
break;
}

// Retrieve information about the interface
const size_t lineNo = spiceInterface->getDeclCodeLoc().line;
llvm::Type *interfaceType = spiceInterface->entry->getType().toLLVMType(irGenerator->context, irGenerator->currentScope);
llvm::Type *interfaceType = spiceInterface->entry->getQualType().toLLVMType(irGenerator->context, irGenerator->currentScope);
assert(interfaceType != nullptr);
llvm::DataLayout dataLayout = irGenerator->module->getDataLayout();
const llvm::StructLayout *structLayout = dataLayout.getStructLayout(reinterpret_cast<llvm::StructType *>(interfaceType));
const uint32_t alignInBits = dataLayout.getABITypeAlign(interfaceType).value();

// Create interface type
// Create interface ty
const std::string mangledName = NameMangling::mangleInterface(*spiceInterface);
llvm::DICompositeType *interfaceDiType = diBuilder->createStructType(
diFile, spiceInterface->name, diFile, lineNo, structLayout->getSizeInBits(), alignInBits,
Expand All @@ -410,7 +410,7 @@ llvm::DIType *DebugInfoGenerator::getDITypeForSymbolType(const ASTNode *node, co
throw CompilerError(UNHANDLED_BRANCH, "Debug Info Type fallthrough"); // GCOV_EXCL_LINE
}

if (symbolType.isConst())
if (ty.isConst())
baseDiType = diBuilder->createQualifiedType(llvm::dwarf::DW_TAG_const_type, baseDiType);

return baseDiType;
Expand Down
4 changes: 2 additions & 2 deletions src/irgenerator/DebugInfoGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace spice::compiler {
// Forward declarations
class IRGenerator;
class SymbolTableEntry;
class Type;
class QualType;
class Function;
class Struct;
class ASTNode;
Expand Down Expand Up @@ -62,7 +62,7 @@ class DebugInfoGenerator {
llvm::DICompositeType *fatPtrTy = nullptr;

// Private methods
[[nodiscard]] llvm::DIType *getDITypeForSymbolType(const ASTNode *node, const Type &symbolType) const;
[[nodiscard]] llvm::DIType *getDITypeForQualType(const ASTNode *node, const QualType &ty) const;
};

} // namespace spice::compiler
15 changes: 7 additions & 8 deletions src/irgenerator/GenBuiltinFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,25 @@ std::any IRGenerator::visitPrintfCall(const PrintfCallNode *node) {
// Collect replacement arguments
for (AssignExprNode *arg : node->args()) {
// Retrieve type of argument
const Type argSymbolType = arg->getEvaluatedSymbolType(manIdx);
llvm::Type *argType = argSymbolType.toLLVMType(context, currentScope);
const QualType argSymbolType = arg->getEvaluatedSymbolType(manIdx);

// Re-map some values
llvm::Value *argVal;
if (argSymbolType.isArray()) {
llvm::Value *argValPtr = resolveAddress(arg);
llvm::Value *indices[2] = {builder.getInt32(0), builder.getInt32(0)};
llvm::Type *argType = argSymbolType.getType().toLLVMType(context, currentScope);
argVal = insertInBoundsGEP(argType, argValPtr, indices);
} else if (argSymbolType.getBaseType().isStringObj()) {
} else if (argSymbolType.getBase().getType().isStringObj()) {
llvm::Value *argValPtr = resolveAddress(arg);
llvm::Type *argBaseType = argSymbolType.getBaseType().toLLVMType(context, currentScope);
llvm::Type *argBaseType = argSymbolType.getBase().getType().toLLVMType(context, currentScope);
argValPtr = insertStructGEP(argBaseType, argValPtr, 0);
argVal = insertLoad(builder.getPtrTy(), argValPtr);
} else {
argVal = resolveValue(arg);
}

// Extend all integer types lower than 32 bit to 32 bit
argType = argVal->getType();
if (argSymbolType.removeReferenceWrapper().isOneOf({TY_SHORT, TY_BYTE, TY_CHAR, TY_BOOL})) {
if (argSymbolType.removeReferenceWrapper().isSigned())
argVal = builder.CreateSExt(argVal, llvm::Type::getInt32Ty(context));
Expand Down Expand Up @@ -89,17 +88,17 @@ std::any IRGenerator::visitAlignofCall(const AlignofCallNode *node) {

std::any IRGenerator::visitLenCall(const LenCallNode *node) {
// Check if the length is fixed and known via the symbol type
Type symbolType = node->assignExpr()->getEvaluatedSymbolType(manIdx);
QualType symbolType = node->assignExpr()->getEvaluatedSymbolType(manIdx);
symbolType = symbolType.removeReferenceWrapper();

llvm::Value *lengthValue;
if (symbolType.is(TY_STRING)) {
llvm::Function *getRawLengthFct = stdFunctionManager.getStringGetRawLengthStringFct();
lengthValue = builder.CreateCall(getRawLengthFct, resolveValue(node->assignExpr()));
} else {
assert(symbolType.isArray() && symbolType.getArraySize() != ARRAY_SIZE_UNKNOWN);
assert(symbolType.isArray() && symbolType.getType().getArraySize() != ARRAY_SIZE_UNKNOWN);
// Return length value
lengthValue = builder.getInt64(symbolType.getArraySize());
lengthValue = builder.getInt64(symbolType.getType().getArraySize());
}
return LLVMExprResult{.value = lengthValue};
}
Expand Down
2 changes: 1 addition & 1 deletion src/irgenerator/GenControlStructures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ std::any IRGenerator::visitForeachLoop(const ForeachLoopNode *node) {
llvm::Value *idxAddrInPair = insertStructGEP(pairTy, pairPtr, 0, "idx_addr");
LLVMExprResult idxResult = {.ptr = idxAddrInPair};
assert(idxAddress != nullptr && idxEntry != nullptr);
doAssignment(idxAddress, idxEntry, idxResult, Type(TY_LONG), true);
doAssignment(idxAddress, idxEntry, idxResult, QualType(TY_LONG), true);
// Store item to item var
llvm::Value *itemAddrInPair = insertStructGEP(pairTy, pairPtr, 1, "item_addr");
LLVMExprResult itemResult = {.refPtr = itemAddrInPair};
Expand Down
Loading

0 comments on commit aa6ea56

Please sign in to comment.