From: Bill Wendling Date: Thu, 31 Jan 2013 20:59:05 +0000 (+0000) Subject: Add support for emitting a string attribute. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=14292a6be51ab57ff425ff263d4134fe46d082c4;p=oota-llvm.git Add support for emitting a string attribute. Attributes that are strings are typically target-dependent attributes. They are of this form in the IR: "attr" "attr" = "val" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174090 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index af9d4fa285c..442860d31b2 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -45,23 +45,24 @@ public: ArrayRef values); AttributeImpl(LLVMContext &C, StringRef data); + LLVMContext &getContext() { return Context; } + bool hasAttribute(Attribute::AttrKind A) const; Constant *getAttributeKind() const { return Kind; } ArrayRef getAttributeValues() const { return Vals; } - LLVMContext &getContext() { return Context; } - ArrayRef getValues() const { return Vals; } - uint64_t getAlignment() const; uint64_t getStackAlignment() const; + /// \brief Equality and non-equality comparison operators. bool operator==(Attribute::AttrKind Kind) const; bool operator!=(Attribute::AttrKind Kind) const; bool operator==(StringRef Kind) const; bool operator!=(StringRef Kind) const; + /// \brief Used when sorting the attributes. bool operator<(const AttributeImpl &AI) const; void Profile(FoldingSetNodeID &ID) const { diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 3a8cfe5ba69..5608cbd47fa 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -106,60 +106,70 @@ unsigned Attribute::getStackAlignment() const { } std::string Attribute::getAsString() const { - if (hasAttribute(Attribute::ZExt)) - return "zeroext"; - if (hasAttribute(Attribute::SExt)) - return "signext"; - if (hasAttribute(Attribute::NoReturn)) - return "noreturn"; - if (hasAttribute(Attribute::NoUnwind)) - return "nounwind"; - if (hasAttribute(Attribute::UWTable)) - return "uwtable"; - if (hasAttribute(Attribute::ReturnsTwice)) - return "returns_twice"; + if (!pImpl) return ""; + + if (hasAttribute(Attribute::AddressSafety)) + return "address_safety"; + if (hasAttribute(Attribute::AlwaysInline)) + return "alwaysinline"; + if (hasAttribute(Attribute::ByVal)) + return "byval"; + if (hasAttribute(Attribute::InlineHint)) + return "inlinehint"; if (hasAttribute(Attribute::InReg)) return "inreg"; + if (hasAttribute(Attribute::MinSize)) + return "minsize"; + if (hasAttribute(Attribute::Naked)) + return "naked"; + if (hasAttribute(Attribute::Nest)) + return "nest"; if (hasAttribute(Attribute::NoAlias)) return "noalias"; if (hasAttribute(Attribute::NoCapture)) return "nocapture"; - if (hasAttribute(Attribute::StructRet)) - return "sret"; - if (hasAttribute(Attribute::ByVal)) - return "byval"; - if (hasAttribute(Attribute::Nest)) - return "nest"; + if (hasAttribute(Attribute::NoDuplicate)) + return "noduplicate"; + if (hasAttribute(Attribute::NoImplicitFloat)) + return "noimplicitfloat"; + if (hasAttribute(Attribute::NoInline)) + return "noinline"; + if (hasAttribute(Attribute::NonLazyBind)) + return "nonlazybind"; + if (hasAttribute(Attribute::NoRedZone)) + return "noredzone"; + if (hasAttribute(Attribute::NoReturn)) + return "noreturn"; + if (hasAttribute(Attribute::NoUnwind)) + return "nounwind"; + if (hasAttribute(Attribute::OptimizeForSize)) + return "optsize"; if (hasAttribute(Attribute::ReadNone)) return "readnone"; if (hasAttribute(Attribute::ReadOnly)) return "readonly"; - if (hasAttribute(Attribute::OptimizeForSize)) - return "optsize"; - if (hasAttribute(Attribute::NoInline)) - return "noinline"; - if (hasAttribute(Attribute::InlineHint)) - return "inlinehint"; - if (hasAttribute(Attribute::AlwaysInline)) - return "alwaysinline"; + if (hasAttribute(Attribute::ReturnsTwice)) + return "returns_twice"; + if (hasAttribute(Attribute::SExt)) + return "signext"; if (hasAttribute(Attribute::StackProtect)) return "ssp"; if (hasAttribute(Attribute::StackProtectReq)) return "sspreq"; if (hasAttribute(Attribute::StackProtectStrong)) return "sspstrong"; - if (hasAttribute(Attribute::NoRedZone)) - return "noredzone"; - if (hasAttribute(Attribute::NoImplicitFloat)) - return "noimplicitfloat"; - if (hasAttribute(Attribute::Naked)) - return "naked"; - if (hasAttribute(Attribute::NonLazyBind)) - return "nonlazybind"; - if (hasAttribute(Attribute::AddressSafety)) - return "address_safety"; - if (hasAttribute(Attribute::MinSize)) - return "minsize"; + if (hasAttribute(Attribute::StructRet)) + return "sret"; + if (hasAttribute(Attribute::UWTable)) + return "uwtable"; + if (hasAttribute(Attribute::ZExt)) + return "zeroext"; + + // FIXME: These should be output like this: + // + // align=4 + // alignstack=8 + // if (hasAttribute(Attribute::StackAlignment)) { std::string Result; Result += "alignstack("; @@ -171,17 +181,38 @@ std::string Attribute::getAsString() const { std::string Result; Result += "align "; Result += utostr(getAlignment()); - Result += ""; return Result; } - if (hasAttribute(Attribute::NoDuplicate)) - return "noduplicate"; + + // Convert target-dependent attributes to strings of the form: + // + // "kind" + // "kind" = "value" + // "kind" = ("value1" "value2" "value3" ) + // + if (ConstantDataArray *CDA = + dyn_cast(pImpl->getAttributeKind())) { + std::string Result; + Result += '\"' + CDA->getAsString().str() + '"'; + + ArrayRef Vals = pImpl->getAttributeValues(); + if (Vals.empty()) return Result; + Result += " = "; + if (Vals.size() > 1) Result += '('; + for (ArrayRef::iterator I = Vals.begin(), E = Vals.end(); + I != E; ) { + ConstantDataArray *CDA = cast(*I++); + Result += '\"' + CDA->getAsString().str() + '"'; + if (I != E) Result += ' '; + } + if (Vals.size() > 1) Result += ')'; + } llvm_unreachable("Unknown attribute"); } bool Attribute::operator==(AttrKind K) const { - return pImpl && *pImpl == K; + return (pImpl && *pImpl == K) || (!pImpl && K == None); } bool Attribute::operator!=(AttrKind K) const { return !(*this == K);