diff options
Diffstat (limited to 'lib/CodeGen')
| -rw-r--r-- | lib/CodeGen/ConstructorGen.cc | 26 | ||||
| -rw-r--r-- | lib/CodeGen/StringValueGen.cc | 6 |
2 files changed, 14 insertions, 18 deletions
diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc index 429138a..15d9300 100644 --- a/lib/CodeGen/ConstructorGen.cc +++ b/lib/CodeGen/ConstructorGen.cc @@ -73,12 +73,7 @@ Value *CodeGen::copyClassValue(const TypeInfo *Type, Value *Address, size_t Lifetime = registerStackObject(Storage, Type->Name, DiagnosticLine); if (Lifetime != size_t(-1)) StackObjects[Lifetime].Temporary = true; Builder->CreateStore(Types->getZeroValue(Type->Name), Storage); - for (const auto &[Name, Field] : Type->Record.Fields) { - if (typeNeedsConstruction(Field.TypeName) && - !emitDefaultConstruct(Field.TypeName, - Builder->CreateStructGEP(Type->LLVMType, Storage, Field.Index), DiagnosticLine)) - return nullptr; - } + if (!emitFieldDefaults(Type, Storage, DiagnosticLine)) return nullptr; if (!FuncGen->emitCall(*Copy, {Storage, Address})) return nullptr; activateStackObject(Lifetime); Transfers.push_back(Lifetime); @@ -109,13 +104,7 @@ bool CodeGen::emitConstruct(const std::string &TypeName, Value *Addr, SaveAndRestore<int> Location(DiagnosticLine, Line); const TypeInfo *Info = resolveType(TypeName); if (!Info) return false; - if (Info->asRecord()) { - for (const auto &[Name, Field] : Info->Record.Fields) { - if (!typeNeedsConstruction(Field.TypeName)) continue; - Value *FieldAddr = Builder->CreateStructGEP(Info->LLVMType, Addr, Field.Index); - if (!emitDefaultConstruct(Field.TypeName, FieldAddr, Line)) return false; - } - } + if (Info->asRecord() && !emitFieldDefaults(Info, Addr, Line)) return false; if (findMethod(TypeName, "NEW")) return emitMethodCall(TypeName, Addr, "NEW", Args, Line) != nullptr; if (!Args.empty()) { @@ -129,6 +118,17 @@ bool CodeGen::emitDefaultConstruct(const std::string &TypeName, Value *Addr, int return emitConstruct(TypeName, Addr, {}, Line); } +// Default-constructs, in declaration order, each field of the record at Addr +// that needs construction. +bool CodeGen::emitFieldDefaults(const TypeInfo *Type, Value *Addr, int Line) { + for (const auto &[Name, Field] : Type->Record.Fields) { + if (!typeNeedsConstruction(Field.TypeName)) continue; + Value *FieldAddr = Builder->CreateStructGEP(Type->LLVMType, Addr, Field.Index); + if (!emitDefaultConstruct(Field.TypeName, FieldAddr, Line)) return false; + } + return true; +} + Value *CodeGen::symbolAddress(const SymbolInfo &Info) { if (!Info.IsReference) return Info.Storage; return Builder->CreateLoad(PointerType::getUnqual(*TheContext), Info.Storage, "object_address"); diff --git a/lib/CodeGen/StringValueGen.cc b/lib/CodeGen/StringValueGen.cc index ce9694c..c07f9a9 100644 --- a/lib/CodeGen/StringValueGen.cc +++ b/lib/CodeGen/StringValueGen.cc @@ -29,11 +29,7 @@ Value *CodeGen::emitStringFromCString(Value *Text) { auto *Storage = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(), Type->LLVMType, "string_value"); Builder->CreateStore(Types->getZeroValue(Type->Name), Storage); - for (const auto &[Name, Field] : Type->Record.Fields) - if (typeNeedsConstruction(Field.TypeName) && - !emitDefaultConstruct(Field.TypeName, - Builder->CreateStructGEP(Type->LLVMType, Storage, Field.Index), DiagnosticLine)) - return nullptr; + if (!emitFieldDefaults(Type, Storage, DiagnosticLine)) return nullptr; if (!FuncGen->emitCall(*Constructor, {Storage, Text})) return nullptr; // The consumer takes ownership, just as with an ordinary class result. return Builder->CreateLoad(Type->LLVMType, Storage, "string"); |
