diff options
Diffstat (limited to 'backend/lib/MIR/EmbeddedIR.cpp')
| -rw-r--r-- | backend/lib/MIR/EmbeddedIR.cpp | 188 |
1 files changed, 148 insertions, 40 deletions
diff --git a/backend/lib/MIR/EmbeddedIR.cpp b/backend/lib/MIR/EmbeddedIR.cpp index d3d5456..b19748e 100644 --- a/backend/lib/MIR/EmbeddedIR.cpp +++ b/backend/lib/MIR/EmbeddedIR.cpp @@ -82,6 +82,13 @@ const EmbeddedIRReference *EmbeddedIRFunction::alloca(std::string_view QueryName return &Allocas[Position->second]; } +const EmbeddedIRReference *EmbeddedIRFunction::value(std::string_view QueryName) const noexcept { + const auto Position = ValueNameToIndex.find(QueryName); + if (Position == ValueNameToIndex.end()) + return nullptr; + return &Values[Position->second]; +} + const EmbeddedIRFunction *EmbeddedIRReferenceIndex::function(std::string_view Name) const noexcept { const auto Position = FunctionNameToIndex.find(Name); if (Position == FunctionNameToIndex.end()) @@ -97,7 +104,7 @@ EmbeddedIRReferenceIndex::globalObject(std::string_view Name) const noexcept { return &GlobalObjects[Position->second]; } -const EmbeddedIRReference * +const EmbeddedIRMetadataDefinition * EmbeddedIRReferenceIndex::metadata(std::string_view Name) const noexcept { const auto Position = MetadataNameToIndex.find(Name); if (Position == MetadataNameToIndex.end()) @@ -105,6 +112,14 @@ EmbeddedIRReferenceIndex::metadata(std::string_view Name) const noexcept { return &MetadataDefinitions[Position->second]; } +const EmbeddedIRTypeDefinition * +EmbeddedIRReferenceIndex::typeDefinition(std::string_view Name) const noexcept { + const auto Position = TypeNameToIndex.find(Name); + if (Position == TypeNameToIndex.end()) + return nullptr; + return &TypeDefinitions[Position->second]; +} + class EmbeddedIRIndexer final { public: EmbeddedIRIndexer(std::string SourceName, std::string SourceText) @@ -299,10 +314,55 @@ private: parseGlobalObject(Line, LineOffset, Position, End); return; } + if (Line[Position] == '%') { + parseTypeDefinition(Line, LineOffset, Position, End); + return; + } if (Line[Position] == '!') parseMetadataDefinition(Line, LineOffset, Position, End); } + void parseTypeDefinition(std::string_view Line, std::size_t LineOffset, + std::size_t Position, std::size_t End) { + auto Name = parseIdentifier(Line, LineOffset, Position, End, '%'); + if (!Name || Failed) + return; + Position = skipHorizontalSpace(Line, Name->End, End); + if (Position >= End || Line[Position] != '=') + return; + ++Position; + Position = skipHorizontalSpace(Line, Position, End); + if (!startsWord(Line, Position, End, "type")) + return; + Position += std::string_view("type").size(); + Position = skipHorizontalSpace(Line, Position, End); + std::size_t DefinitionEnd = End; + while (DefinitionEnd > Position && isHorizontalSpace(Line[DefinitionEnd - 1])) + --DefinitionEnd; + if (Position == DefinitionEnd) { + diagnose(Name->Range.Begin.Offset, Name->Range.End.Offset, + "embedded LLVM IR type definition is empty"); + return; + } + if (Index.TypeNameToIndex.contains(Name->Name)) { + diagnose(Name->Range.Begin.Offset, Name->Range.End.Offset, + "duplicate embedded LLVM IR type definition"); + return; + } + const std::size_t TypeIndex = Index.TypeDefinitions.size(); + const bool NumericName = !Name->Name.empty() && Name->Name.front() >= '0' && + Name->Name.front() <= '9'; + Index.TypeNameToIndex.emplace(Name->Name, TypeIndex); + Index.TypeDefinitions.push_back(EmbeddedIRTypeDefinition{ + .Name = std::move(Name->Name), + .Range = Name->Range, + .Definition = std::string(Line.substr(Position, DefinitionEnd - Position)), + .DefinitionRange = + Index.Source.range(LineOffset + Position, LineOffset + DefinitionEnd), + .NumericName = NumericName, + }); + } + void parseTargetFact(std::string_view Line, std::size_t LineOffset, std::size_t Position, std::size_t End) { Position += std::string_view("target").size(); @@ -426,6 +486,24 @@ private: } if (InQuote) continue; + if (Character == '%' && HeaderParenthesisDepth != 0 && ActiveFunction) { + const std::size_t IdentifierBegin = Position; + auto Name = parseIdentifier(Line, LineOffset, Position, End, '%'); + if (!Name || Failed) + return; + const std::size_t Following = skipHorizontalSpace(Line, Name->End, End); + std::size_t Previous = IdentifierBegin; + while (Previous > 0 && isHorizontalSpace(Line[Previous - 1])) + --Previous; + const bool HasTypeBefore = Previous != 0 && Line[Previous - 1] != '(' && + Line[Previous - 1] != ','; + const bool EndsParameter = Following == End || Line[Following] == ',' || + Line[Following] == ')'; + if (HasTypeBefore && EndsParameter) + addLocalValue(*Name, Index.Functions[ActiveFunction.value()]); + Position = Name->End - 1; + continue; + } if (Character == '(') { ++HeaderParenthesisDepth; continue; @@ -447,6 +525,21 @@ private: } } + void addLocalValue(const ParsedIdentifier &Name, EmbeddedIRFunction &Function) { + if (Function.ValueNameToIndex.contains(Name.Name) || + Function.BlockNameToIndex.contains(Name.Name)) { + diagnose(Name.Range.Begin.Offset, Name.Range.End.Offset, + "duplicate embedded LLVM IR local value or basic block name"); + return; + } + const std::size_t ValueIndex = Function.Values.size(); + Function.ValueNameToIndex.emplace(Name.Name, ValueIndex); + Function.Values.push_back(EmbeddedIRReference{ + .Name = Name.Name, + .Range = Name.Range, + }); + } + void parseActiveFunctionLine(std::string_view Line, std::size_t LineOffset, std::size_t End) { if (FunctionBraceDepth == 0) { parseFunctionHeaderRemainder(Line, LineOffset, 0, End); @@ -498,7 +591,7 @@ private: parseBlockLabel(Line, LineOffset, Begin, BodyEnd, Function); if (Failed) return; - parseAlloca(Line, LineOffset, Begin, BodyEnd, Function); + parseLocalValueDefinition(Line, LineOffset, Begin, BodyEnd, Function); if (Failed) return; @@ -524,6 +617,11 @@ private: "duplicate embedded LLVM IR basic block label"); return; } + if (Function.ValueNameToIndex.contains(Name->Name)) { + diagnose(Name->Range.Begin.Offset, Name->Range.End.Offset, + "duplicate embedded LLVM IR local value or basic block name"); + return; + } const std::size_t BlockIndex = Function.Blocks.size(); Function.BlockNameToIndex.emplace(Name->Name, BlockIndex); Function.Blocks.push_back(EmbeddedIRReference{ @@ -532,46 +630,33 @@ private: }); } - void parseAlloca(std::string_view Line, std::size_t LineOffset, std::size_t Begin, - std::size_t End, EmbeddedIRFunction &Function) { - bool InQuote = false; - for (std::size_t Position = Begin; Position < End; ++Position) { - if (InQuote && Line[Position] == '\\' && Position + 2 < End && - isHexDigit(Line[Position + 1]) && isHexDigit(Line[Position + 2])) { - Position += 2; - continue; - } - if (Line[Position] == '"') { - InQuote = !InQuote; - continue; - } - if (InQuote || Line[Position] != '%') - continue; + void parseLocalValueDefinition(std::string_view Line, std::size_t LineOffset, + std::size_t Begin, std::size_t End, + EmbeddedIRFunction &Function) { + std::size_t Position = skipHorizontalSpace(Line, Begin, End); + if (Position >= End || Line[Position] != '%') + return; + auto Name = parseIdentifier(Line, LineOffset, Position, End, '%'); + if (!Name || Failed) + return; + Position = skipHorizontalSpace(Line, Name->End, End); + if (Position >= End || Line[Position] != '=') + return; + ++Position; + Position = skipHorizontalSpace(Line, Position, End); - auto Name = parseIdentifier(Line, LineOffset, Position, End, '%'); - if (!Name || Failed) - return; - Position = skipHorizontalSpace(Line, Name->End, End); - if (Position >= End || Line[Position] != '=') - continue; - ++Position; - Position = skipHorizontalSpace(Line, Position, End); - if (!startsWord(Line, Position, End, "alloca")) - continue; + addLocalValue(*Name, Function); + if (Failed) + return; - if (Function.AllocaNameToIndex.contains(Name->Name)) { - diagnose(Name->Range.Begin.Offset, Name->Range.End.Offset, - "duplicate embedded LLVM IR alloca name"); - return; - } - const std::size_t AllocaIndex = Function.Allocas.size(); - Function.AllocaNameToIndex.emplace(Name->Name, AllocaIndex); - Function.Allocas.push_back(EmbeddedIRReference{ - .Name = std::move(Name->Name), - .Range = Name->Range, - }); + if (!startsWord(Line, Position, End, "alloca")) return; - } + const std::size_t AllocaIndex = Function.Allocas.size(); + Function.AllocaNameToIndex.emplace(Name->Name, AllocaIndex); + Function.Allocas.push_back(EmbeddedIRReference{ + .Name = std::move(Name->Name), + .Range = Name->Range, + }); } void parseGlobalObject(std::string_view Line, std::size_t LineOffset, std::size_t Position, @@ -608,6 +693,28 @@ private: Position = skipHorizontalSpace(Line, Name->End, End); if (Position >= End || Line[Position] != '=') return; + ++Position; + Position = skipHorizontalSpace(Line, Position, End); + if (startsWord(Line, Position, End, "distinct")) { + Position += std::string_view("distinct").size(); + Position = skipHorizontalSpace(Line, Position, End); + } + + std::string DynamicType; + if (Position < End && Line[Position] == '!') { + ++Position; + if (Position < End && Line[Position] == '{') { + DynamicType = "MDTuple"; + } else if (Position < End && Line[Position] == '"') { + DynamicType = "MDString"; + } else { + const std::size_t TypeBegin = Position; + while (Position < End && isIdentifierBody(Line[Position])) + ++Position; + if (Position != TypeBegin) + DynamicType = std::string(Line.substr(TypeBegin, Position - TypeBegin)); + } + } if (Index.MetadataNameToIndex.contains(Name->Name)) { diagnose(Name->Range.Begin.Offset, Name->Range.End.Offset, "duplicate embedded LLVM IR metadata definition"); @@ -615,9 +722,10 @@ private: } const std::size_t MetadataIndex = Index.MetadataDefinitions.size(); Index.MetadataNameToIndex.emplace(Name->Name, MetadataIndex); - Index.MetadataDefinitions.push_back(EmbeddedIRReference{ + Index.MetadataDefinitions.push_back(EmbeddedIRMetadataDefinition{ .Name = std::move(Name->Name), .Range = Name->Range, + .DynamicType = std::move(DynamicType), }); } |
