summaryrefslogtreecommitdiffstats
path: root/lib/IR
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-01-31 20:59:05 +0000
committerBill Wendling <isanbard@gmail.com>2013-01-31 20:59:05 +0000
commit14292a6be51ab57ff425ff263d4134fe46d082c4 (patch)
tree979145ca073962db3a59de9efab1cdb69db4b7ba /lib/IR
parentb62fb4ba5cf61070486287da393ada566b4ad4ed (diff)
downloadexternal_llvm-14292a6be51ab57ff425ff263d4134fe46d082c4.zip
external_llvm-14292a6be51ab57ff425ff263d4134fe46d082c4.tar.gz
external_llvm-14292a6be51ab57ff425ff263d4134fe46d082c4.tar.bz2
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
Diffstat (limited to 'lib/IR')
-rw-r--r--lib/IR/AttributeImpl.h7
-rw-r--r--lib/IR/Attributes.cpp115
2 files changed, 77 insertions, 45 deletions
diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h
index af9d4fa..442860d 100644
--- a/lib/IR/AttributeImpl.h
+++ b/lib/IR/AttributeImpl.h
@@ -45,23 +45,24 @@ public:
ArrayRef<Constant*> values);
AttributeImpl(LLVMContext &C, StringRef data);
+ LLVMContext &getContext() { return Context; }
+
bool hasAttribute(Attribute::AttrKind A) const;
Constant *getAttributeKind() const { return Kind; }
ArrayRef<Constant*> getAttributeValues() const { return Vals; }
- LLVMContext &getContext() { return Context; }
- ArrayRef<Constant*> 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 3a8cfe5..5608cbd 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<ConstantDataArray>(pImpl->getAttributeKind())) {
+ std::string Result;
+ Result += '\"' + CDA->getAsString().str() + '"';
+
+ ArrayRef<Constant*> Vals = pImpl->getAttributeValues();
+ if (Vals.empty()) return Result;
+ Result += " = ";
+ if (Vals.size() > 1) Result += '(';
+ for (ArrayRef<Constant*>::iterator I = Vals.begin(), E = Vals.end();
+ I != E; ) {
+ ConstantDataArray *CDA = cast<ConstantDataArray>(*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);