diff options
Diffstat (limited to 'llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h')
-rw-r--r-- | llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h | 90 |
1 files changed, 84 insertions, 6 deletions
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h index 138df786eaf3..392c87054d43 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -15,16 +15,94 @@ namespace llvm { class RISCVTargetELFStreamer : public RISCVTargetStreamer { +private: + enum class AttributeType { Hidden, Numeric, Text, NumericAndText }; + + struct AttributeItem { + AttributeType Type; + unsigned Tag; + unsigned IntValue; + std::string StringValue; + }; + + StringRef CurrentVendor; + SmallVector<AttributeItem, 64> Contents; + + MCSection *AttributeSection = nullptr; + + AttributeItem *getAttributeItem(unsigned Attribute) { + for (size_t i = 0; i < Contents.size(); ++i) + if (Contents[i].Tag == Attribute) + return &Contents[i]; + return nullptr; + } + + void setAttributeItem(unsigned Attribute, unsigned Value, + bool OverwriteExisting) { + // Look for existing attribute item. + if (AttributeItem *Item = getAttributeItem(Attribute)) { + if (!OverwriteExisting) + return; + Item->Type = AttributeType::Numeric; + Item->IntValue = Value; + return; + } + + // Create new attribute item. + Contents.push_back({AttributeType::Numeric, Attribute, Value, ""}); + } + + void setAttributeItem(unsigned Attribute, StringRef Value, + bool OverwriteExisting) { + // Look for existing attribute item. + if (AttributeItem *Item = getAttributeItem(Attribute)) { + if (!OverwriteExisting) + return; + Item->Type = AttributeType::Text; + Item->StringValue = std::string(Value); + return; + } + + // Create new attribute item. + Contents.push_back({AttributeType::Text, Attribute, 0, std::string(Value)}); + } + + void setAttributeItems(unsigned Attribute, unsigned IntValue, + StringRef StringValue, bool OverwriteExisting) { + // Look for existing attribute item. + if (AttributeItem *Item = getAttributeItem(Attribute)) { + if (!OverwriteExisting) + return; + Item->Type = AttributeType::NumericAndText; + Item->IntValue = IntValue; + Item->StringValue = std::string(StringValue); + return; + } + + // Create new attribute item. + Contents.push_back({AttributeType::NumericAndText, Attribute, IntValue, + std::string(StringValue)}); + } + + void emitAttribute(unsigned Attribute, unsigned Value) override; + void emitTextAttribute(unsigned Attribute, StringRef String) override; + void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, + StringRef StringValue) override; + void finishAttributeSection() override; + size_t calculateContentSize() const; + public: MCELFStreamer &getStreamer(); RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); - virtual void emitDirectiveOptionPush(); - virtual void emitDirectiveOptionPop(); - virtual void emitDirectiveOptionRVC(); - virtual void emitDirectiveOptionNoRVC(); - virtual void emitDirectiveOptionRelax(); - virtual void emitDirectiveOptionNoRelax(); + void emitDirectiveOptionPush() override; + void emitDirectiveOptionPop() override; + void emitDirectiveOptionPIC() override; + void emitDirectiveOptionNoPIC() override; + void emitDirectiveOptionRVC() override; + void emitDirectiveOptionNoRVC() override; + void emitDirectiveOptionRelax() override; + void emitDirectiveOptionNoRelax() override; }; } #endif |