summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Attributes.h50
-rw-r--r--lib/AsmParser/LLParser.cpp40
-rw-r--r--lib/AsmParser/LLParser.h2
-rw-r--r--lib/VMCore/Attributes.cpp22
4 files changed, 92 insertions, 22 deletions
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index 07e2154aa3..c3198a555f 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -144,12 +144,50 @@ class AttributesImpl;
class Attributes {
// Currently, we need less than 64 bits.
AttributesImpl Attrs;
-
+#if 0
+ enum Attribute {
+ None = 0, ///< No attributes have been set
+ ZExt = 1 << 0, ///< Zero extended before/after call
+ SExt = 1 << 1, ///< Sign extended before/after call
+ NoReturn = 1 << 2, ///< Mark the function as not returning
+ InReg = 1 << 3, ///< Force argument to be passed in register
+ StructRet = 1 << 4, ///< Hidden pointer to structure to return
+ NoUnwind = 1 << 5, ///< Function doesn't unwind stack
+ NoAlias = 1 << 6, ///< Considered to not alias after call
+ ByVal = 1 << 7, ///< Pass structure by value
+ Nest = 1 << 8, ///< Nested function static chain
+ ReadNone = 1 << 9, ///< Function does not access memory
+ ReadOnly = 1 << 10, ///< Function only reads from memory
+ NoInline = 1 << 11, ///< inline=never
+ AlwaysInline = 1 << 12, ///< inline=always
+ OptimizeForSize = 1 << 13, ///< opt_size
+ StackProtect = 1 << 14, ///< Stack protection.
+ StackProtectReq = 1 << 15, ///< Stack protection required.
+ Alignment = 31 << 16, ///< Alignment of parameter (5 bits)
+ ///< stored as log2 of alignment with +1 bias
+ ///< 0 means unaligned different from align 1
+ NoCapture = 1 << 21, ///< Function creates no aliases of pointer
+ NoRedZone = 1 << 22, ///< Disable redzone
+ NoImplicitFloat = 1 << 23, ///< Disable implicit floating point insts
+ Naked = 1 << 24, ///< Naked function
+ InlineHint = 1 << 25, ///< Source said inlining was desirable
+ StackAlignment = 7 << 26, ///< Alignment of stack for function (3 bits)
+ ///< stored as log2 of alignment with +1 bias 0
+ ///< means unaligned (different from
+ ///< alignstack={1))
+ ReturnsTwice = 1 << 29, ///< Function can return twice
+ UWTable = 1 << 30, ///< Function must be in a unwind table
+ NonLazyBind = 1U << 31, ///< Function is called early and/or
+ ///< often, so lazy binding isn't worthwhile
+ AddressSafety = 1ULL << 32 ///< Address safety checking is on.
+ };
+#endif
explicit Attributes(AttributesImpl *A);
public:
Attributes() : Attrs(0) {}
explicit Attributes(uint64_t Val);
/*implicit*/ Attributes(Attribute::AttrConst Val);
+ Attributes(const Attributes &A);
class Builder {
friend class Attributes;
@@ -158,6 +196,13 @@ public:
Builder() : Bits(0) {}
Builder(const Attributes &A) : Bits(A.Raw()) {}
+ void clear() { Bits = 0; }
+
+ bool hasAttributes() const;
+ bool hasAlignmentAttr() const;
+
+ uint64_t getAlignment() const;
+
void addAddressSafetyAttr();
void addAlwaysInlineAttr();
void addByValAttr();
@@ -212,6 +257,9 @@ public:
void removeStructRetAttr();
void removeUWTableAttr();
void removeZExtAttr();
+
+ void removeAlignmentAttr();
+ void removeStackAlignmentAttr();
};
/// get - Return a uniquified Attributes object. This takes the uniquified
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index fea4179330..048afae9f1 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -916,16 +916,16 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
/// indicates what kind of attribute list this is: 0: function arg, 1: result,
/// 2: function attr.
-bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) {
- Attributes::Builder B;
+bool LLParser::ParseOptionalAttrs(Attributes::Builder &B, unsigned AttrKind) {
LocTy AttrLoc = Lex.getLoc();
bool HaveError = false;
+ B.clear();
+
while (1) {
lltok::Kind Token = Lex.getKind();
switch (Token) {
default: // End of attributes.
- Attrs = Attributes::get(B); // FIXME: Use the other version of get().
return HaveError;
case lltok::kw_zeroext: B.addZExtAttr(); break;
case lltok::kw_signext: B.addSExtAttr(); break;
@@ -1435,7 +1435,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
// Parse the argument.
LocTy ArgLoc;
Type *ArgTy = 0;
- Attributes ArgAttrs;
+ Attributes::Builder ArgAttrs;
Value *V;
if (ParseType(ArgTy, ArgLoc))
return true;
@@ -1443,7 +1443,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
// Otherwise, handle normal operands.
if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS))
return true;
- ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs));
+ ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(ArgAttrs)));
}
Lex.Lex(); // Lex the ')'.
@@ -1475,7 +1475,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
} else {
LocTy TypeLoc = Lex.getLoc();
Type *ArgTy = 0;
- Attributes Attrs;
+ Attributes::Builder Attrs;
std::string Name;
if (ParseType(ArgTy) ||
@@ -1492,7 +1492,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name));
while (EatIfPresent(lltok::comma)) {
// Handle ... at end of arg list.
@@ -1518,7 +1518,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name));
}
}
@@ -2672,7 +2672,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
unsigned Linkage;
unsigned Visibility;
- Attributes RetAttrs;
+ Attributes::Builder RetAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc = Lex.getLoc();
@@ -2736,7 +2736,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
- Attributes FuncAttrs;
+ Attributes::Builder FuncAttrs;
std::string Section;
unsigned Alignment;
std::string GC;
@@ -2755,9 +2755,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
return true;
// If the alignment was parsed as an attribute, move to the alignment field.
- if (FuncAttrs & Attribute::Alignment) {
+ if (FuncAttrs.hasAlignmentAttr()) {
Alignment = FuncAttrs.getAlignment();
- FuncAttrs &= ~Attribute::Alignment;
+ FuncAttrs.removeAlignmentAttr();
}
// Okay, if we got here, the function is syntactically valid. Convert types
@@ -2766,7 +2766,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
ParamTypeList.push_back(ArgList[i].Ty);
@@ -2775,7 +2775,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
}
if (FuncAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs));
+ Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FuncAttrs)));
AttrListPtr PAL = AttrListPtr::get(Attrs);
@@ -3247,7 +3247,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
- Attributes RetAttrs, FnAttrs;
+ Attributes::Builder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
@@ -3293,7 +3293,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
// Set up the Attributes for the function.
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
SmallVector<Value*, 8> Args;
@@ -3321,7 +3321,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
return Error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
+ Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs)));
// Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs);
@@ -3646,7 +3646,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
/// ParameterList OptionalAttrs
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
- Attributes RetAttrs, FnAttrs;
+ Attributes::Builder RetAttrs, FnAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
@@ -3689,7 +3689,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
// Set up the Attributes for the function.
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs)));
SmallVector<Value*, 8> Args;
@@ -3717,7 +3717,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
return Error(CallLoc, "not enough parameters specified for call");
if (FnAttrs.hasAttributes())
- Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
+ Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs)));
// Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs);
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 257c726229..671eaf6429 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -175,7 +175,7 @@ namespace llvm {
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
- bool ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind);
+ bool ParseOptionalAttrs(Attributes::Builder &Attrs, unsigned AttrKind);
bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage);
bool ParseOptionalLinkage(unsigned &Linkage) {
bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);
diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp
index 1fcebdf5ba..6905e4df39 100644
--- a/lib/VMCore/Attributes.cpp
+++ b/lib/VMCore/Attributes.cpp
@@ -33,6 +33,8 @@ Attributes::Attributes(Attribute::AttrConst Val) : Attrs(Val.v) {}
Attributes::Attributes(AttributesImpl *A) : Attrs(A->Bits) {}
+Attributes::Attributes(const Attributes &A) : Attrs(A.Attrs) {}
+
// FIXME: This is temporary until we have implemented the uniquified version of
// AttributesImpl.
Attributes Attributes::get(Attributes::Builder &B) {
@@ -451,6 +453,26 @@ void Attributes::Builder::removeZExtAttr() {
Bits &= ~Attribute::ZExt_i;
}
+void Attributes::Builder::removeAlignmentAttr() {
+ Bits &= ~Attribute::Alignment_i;
+}
+void Attributes::Builder::removeStackAlignmentAttr() {
+ Bits &= ~Attribute::StackAlignment_i;
+}
+
+bool Attributes::Builder::hasAttributes() const {
+ return Bits != 0;
+}
+bool Attributes::Builder::hasAlignmentAttr() const {
+ return Bits & Attribute::Alignment_i;
+}
+
+uint64_t Attributes::Builder::getAlignment() const {
+ if (!hasAlignmentAttr())
+ return 0;
+ return 1U << (((Bits & Attribute::Alignment_i) >> 16) - 1);
+}
+
//===----------------------------------------------------------------------===//
// AttributeImpl Definition
//===----------------------------------------------------------------------===//