summaryrefslogtreecommitdiff
path: root/lib/AsmParser
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-02-06 06:52:58 +0000
committerBill Wendling <isanbard@gmail.com>2013-02-06 06:52:58 +0000
commit95ce4c2ffb0ff31a79b060fb112659322a5be3bf (patch)
treea0c49a46b4877c7b3ac712892d8c6601dc4fed35 /lib/AsmParser
parent97fe3d95110db54908527e547187b3007185e46c (diff)
downloadllvm-95ce4c2ffb0ff31a79b060fb112659322a5be3bf.tar.gz
llvm-95ce4c2ffb0ff31a79b060fb112659322a5be3bf.tar.bz2
llvm-95ce4c2ffb0ff31a79b060fb112659322a5be3bf.tar.xz
Initial submission for the attribute group feature.
Attribute groups are of the form: #0 = attributes { noinline "no-sse" "cpu"="cortex-a8" alignstack=4 } Target-dependent attributes are represented as strings. Attributes can have optional values associated with them. E.g., the "cpu" attribute has the value "cortex-a8". Target-independent attributes are listed as enums inside the attribute classes. Multiple attribute groups can be referenced by the same object. In that case, the attributes are merged together. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174493 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser')
-rw-r--r--lib/AsmParser/LLLexer.cpp60
-rw-r--r--lib/AsmParser/LLLexer.h1
-rw-r--r--lib/AsmParser/LLParser.cpp99
-rw-r--r--lib/AsmParser/LLParser.h5
-rw-r--r--lib/AsmParser/LLToken.h43
5 files changed, 167 insertions, 41 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 72136d058e..2256124043 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -226,6 +226,7 @@ lltok::Kind LLLexer::LexToken() {
SkipLineComment();
return LexToken();
case '!': return LexExclaim();
+ case '#': return LexHash();
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '-':
@@ -394,6 +395,24 @@ lltok::Kind LLLexer::LexExclaim() {
return lltok::exclaim;
}
+/// LexHash - Lex all tokens that start with a # character:
+/// AttrGrpID ::= #[0-9]+
+lltok::Kind LLLexer::LexHash() {
+ // Handle AttrGrpID: #[0-9]+
+ if (isdigit(CurPtr[0])) {
+ for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr)
+ /*empty*/;
+
+ uint64_t Val = atoull(TokStart+1, CurPtr);
+ if ((unsigned)Val != Val)
+ Error("invalid value number (too large)!");
+ UIntVal = unsigned(Val);
+ return lltok::AttrGrpID;
+ }
+
+ return lltok::Error;
+}
+
/// LexIdentifier: Handle several related productions:
/// Label [-a-zA-Z$._0-9]+:
/// IntegerType i[0-9]+
@@ -531,35 +550,36 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(cc);
KEYWORD(c);
- KEYWORD(signext);
- KEYWORD(zeroext);
+ KEYWORD(attributes);
+
+ KEYWORD(address_safety);
+ KEYWORD(alwaysinline);
+ KEYWORD(byval);
+ KEYWORD(inlinehint);
KEYWORD(inreg);
- KEYWORD(sret);
- KEYWORD(nounwind);
- KEYWORD(noreturn);
+ KEYWORD(minsize);
+ KEYWORD(naked);
+ KEYWORD(nest);
KEYWORD(noalias);
KEYWORD(nocapture);
- KEYWORD(byval);
- KEYWORD(nest);
+ KEYWORD(noduplicate);
+ KEYWORD(noimplicitfloat);
+ KEYWORD(noinline);
+ KEYWORD(nonlazybind);
+ KEYWORD(noredzone);
+ KEYWORD(noreturn);
+ KEYWORD(nounwind);
+ KEYWORD(optsize);
KEYWORD(readnone);
KEYWORD(readonly);
- KEYWORD(uwtable);
KEYWORD(returns_twice);
-
- KEYWORD(inlinehint);
- KEYWORD(noinline);
- KEYWORD(alwaysinline);
- KEYWORD(optsize);
+ KEYWORD(signext);
+ KEYWORD(sret);
KEYWORD(ssp);
KEYWORD(sspreq);
KEYWORD(sspstrong);
- KEYWORD(noredzone);
- KEYWORD(noimplicitfloat);
- KEYWORD(naked);
- KEYWORD(nonlazybind);
- KEYWORD(address_safety);
- KEYWORD(minsize);
- KEYWORD(noduplicate);
+ KEYWORD(uwtable);
+ KEYWORD(zeroext);
KEYWORD(type);
KEYWORD(opaque);
diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h
index 1a307a8bec..85703c766b 100644
--- a/lib/AsmParser/LLLexer.h
+++ b/lib/AsmParser/LLLexer.h
@@ -81,6 +81,7 @@ namespace llvm {
lltok::Kind LexPercent();
lltok::Kind LexQuote();
lltok::Kind Lex0x();
+ lltok::Kind LexHash();
uint64_t atoull(const char *Buffer, const char *End);
uint64_t HexIntToVal(const char *Buffer, const char *End);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 2b6b165837..22c21c62b9 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -174,7 +174,8 @@ bool LLParser::ParseTopLevelEntities() {
case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break;
case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break;
case lltok::exclaim: if (ParseStandaloneMetadata()) return true; break;
- case lltok::MetadataVar: if (ParseNamedMetadata()) return true; break;
+ case lltok::MetadataVar:if (ParseNamedMetadata()) return true; break;
+ case lltok::AttrGrpID: if (ParseUnnamedAttrGrp()) return true; break;
// The Global variable production with no name can have many different
// optional leading prefixes, the production is:
@@ -740,6 +741,102 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
return false;
}
+/// ParseUnnamedAttrGrp
+/// ::= AttrGrpID '=' '{' AttrValPair+ '}'
+bool LLParser::ParseUnnamedAttrGrp() {
+ assert(Lex.getKind() == lltok::AttrGrpID);
+ LocTy AttrGrpLoc = Lex.getLoc();
+ unsigned VarID = Lex.getUIntVal();
+ Lex.Lex();
+
+ if (ParseToken(lltok::equal, "expected '=' here") ||
+ ParseToken(lltok::kw_attributes, "expected 'attributes' keyword here") ||
+ ParseToken(lltok::lbrace, "expected '{' here") ||
+ ParseAttributeValuePairs(ForwardRefAttrBuilder[VarID]) ||
+ ParseToken(lltok::rbrace, "expected end of attribute group"))
+ return true;
+
+ if (!ForwardRefAttrBuilder[VarID].hasAttributes())
+ return Error(AttrGrpLoc, "attribute group has no attributes");
+
+ return false;
+}
+
+/// ParseAttributeValuePairs
+/// ::= <attr> | <attr> '=' <value>
+bool LLParser::ParseAttributeValuePairs(AttrBuilder &B) {
+ while (true) {
+ lltok::Kind Token = Lex.getKind();
+ switch (Token) {
+ default:
+ return Error(Lex.getLoc(), "unterminated attribute group");
+ case lltok::rbrace:
+ // Finished.
+ return false;
+
+ // Target-dependent attributes:
+ case lltok::StringConstant: {
+ std::string Attr = Lex.getStrVal();
+ Lex.Lex();
+ std::string Val;
+ if (EatIfPresent(lltok::equal) &&
+ ParseStringConstant(Val))
+ return true;
+
+ B.addAttribute(Attr, Val);
+ break;
+ }
+
+ // Target-independent attributes:
+ case lltok::kw_align: {
+ unsigned Alignment;
+ if (ParseToken(lltok::equal, "expected '=' here") ||
+ ParseUInt32(Alignment))
+ return true;
+ B.addAlignmentAttr(Alignment);
+ break;
+ }
+ case lltok::kw_alignstack: {
+ unsigned Alignment;
+ if (ParseToken(lltok::equal, "expected '=' here") ||
+ ParseUInt32(Alignment))
+ return true;
+ B.addStackAlignmentAttr(Alignment);
+ break;
+ }
+ case lltok::kw_address_safety: B.addAttribute(Attribute::AddressSafety); break;
+ case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
+ case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break;
+ case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
+ case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
+ case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
+ case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
+ case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
+ case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
+ case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break;
+ case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
+ case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break;
+ case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
+ case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
+ case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
+ case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
+ case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
+ case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
+ case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
+ case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
+ case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break;
+ case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
+ case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break;
+ case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
+ case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
+ case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break;
+ case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
+ case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
+ }
+
+ Lex.Lex();
+ }
+}
//===----------------------------------------------------------------------===//
// GlobalValue Reference/Resolution Routines.
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index d8de77908c..131331a5bc 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -125,6 +125,9 @@ namespace llvm {
std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >
ForwardRefBlockAddresses;
+ // Attribute builder reference information.
+ std::map<unsigned, AttrBuilder> ForwardRefAttrBuilder;
+
public:
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
Context(m->getContext()), Lex(F, SM, Err, m->getContext()),
@@ -236,6 +239,8 @@ namespace llvm {
bool ParseMDString(MDString *&Result);
bool ParseMDNodeID(MDNode *&Result);
bool ParseMDNodeID(MDNode *&Result, unsigned &SlotNo);
+ bool ParseUnnamedAttrGrp();
+ bool ParseAttributeValuePairs(AttrBuilder &B);
// Type Parsing.
bool ParseType(Type *&Result, bool AllowVoid = false);
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index c9ecd21470..8c18a3be60 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -30,6 +30,7 @@ namespace lltok {
lparen, rparen, // ( )
backslash, // \ (not /)
exclaim, // !
+ hash, // #
kw_x,
kw_true, kw_false,
@@ -90,35 +91,36 @@ namespace lltok {
kw_ptx_kernel, kw_ptx_device,
kw_spir_kernel, kw_spir_func,
- kw_signext,
- kw_zeroext,
+ // Attributes:
+ kw_attributes,
+ kw_alwaysinline,
+ kw_address_safety,
+ kw_byval,
+ kw_inlinehint,
kw_inreg,
- kw_sret,
- kw_nounwind,
- kw_noreturn,
+ kw_minsize,
+ kw_naked,
+ kw_nest,
kw_noalias,
kw_nocapture,
- kw_byval,
- kw_nest,
+ kw_noduplicate,
+ kw_noimplicitfloat,
+ kw_noinline,
+ kw_nonlazybind,
+ kw_noredzone,
+ kw_noreturn,
+ kw_nounwind,
+ kw_optsize,
kw_readnone,
kw_readonly,
- kw_uwtable,
kw_returns_twice,
-
- kw_inlinehint,
- kw_noinline,
- kw_alwaysinline,
- kw_optsize,
+ kw_signext,
kw_ssp,
kw_sspreq,
kw_sspstrong,
- kw_noredzone,
- kw_noimplicitfloat,
- kw_naked,
- kw_nonlazybind,
- kw_address_safety,
- kw_minsize,
- kw_noduplicate,
+ kw_sret,
+ kw_uwtable,
+ kw_zeroext,
kw_type,
kw_opaque,
@@ -155,6 +157,7 @@ namespace lltok {
// Unsigned Valued tokens (UIntVal).
GlobalID, // @42
LocalVarID, // %42
+ AttrGrpID, // #42
// String valued tokens (StrVal).
LabelStr, // foo: