Skip to content

Commit baad55c

Browse files
committed
Parse the attribute group reference on a function.
Attribute references are of this form: define void @foo() #0 #1 #2 { ... } Parse them for function attributes. If there's more than one reference, then they are merged together. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174697 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 61b97b8 commit baad55c

File tree

2 files changed

+94
-8
lines changed

2 files changed

+94
-8
lines changed

lib/AsmParser/LLParser.cpp

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,64 @@ bool LLParser::ValidateEndOfModule() {
6565
ForwardRefInstMetadata.clear();
6666
}
6767

68+
// Handle any function attribute group forward references.
69+
for (std::map<Value*, std::vector<unsigned> >::iterator
70+
I = ForwardRefAttrGroups.begin(), E = ForwardRefAttrGroups.end();
71+
I != E; ++I) {
72+
Value *V = I->first;
73+
std::vector<unsigned> &Vec = I->second;
74+
AttrBuilder B;
75+
76+
for (std::vector<unsigned>::iterator VI = Vec.begin(), VE = Vec.end();
77+
VI != VE; ++VI)
78+
B.merge(NumberedAttrBuilders[*VI]);
79+
80+
if (Function *Fn = dyn_cast<Function>(V)) {
81+
AttributeSet AS = Fn->getAttributes();
82+
AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex);
83+
AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex,
84+
AS.getFnAttributes());
85+
86+
FnAttrs.merge(B);
87+
88+
// If the alignment was parsed as an attribute, move to the alignment
89+
// field.
90+
if (FnAttrs.hasAlignmentAttr()) {
91+
Fn->setAlignment(FnAttrs.getAlignment());
92+
FnAttrs.removeAttribute(Attribute::Alignment);
93+
}
94+
95+
AS = AS.addAttributes(Context, AttributeSet::FunctionIndex,
96+
AttributeSet::get(Context,
97+
AttributeSet::FunctionIndex,
98+
FnAttrs));
99+
Fn->setAttributes(AS);
100+
} else if (CallInst *CI = dyn_cast<CallInst>(V)) {
101+
AttributeSet AS = CI->getAttributes();
102+
AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex);
103+
AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex,
104+
AS.getFnAttributes());
105+
106+
AS = AS.addAttributes(Context, AttributeSet::FunctionIndex,
107+
AttributeSet::get(Context,
108+
AttributeSet::FunctionIndex,
109+
FnAttrs));
110+
CI->setAttributes(AS);
111+
} else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) {
112+
AttributeSet AS = II->getAttributes();
113+
AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex);
114+
AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex,
115+
AS.getFnAttributes());
116+
117+
AS = AS.addAttributes(Context, AttributeSet::FunctionIndex,
118+
AttributeSet::get(Context,
119+
AttributeSet::FunctionIndex,
120+
FnAttrs));
121+
II->setAttributes(AS);
122+
} else {
123+
llvm_unreachable("invalid object with forward attribute group reference");
124+
}
125+
}
68126

69127
// If there are entries in ForwardRefBlockAddresses at this point, they are
70128
// references after the function was defined. Resolve those now.
@@ -747,24 +805,27 @@ bool LLParser::ParseUnnamedAttrGrp() {
747805
assert(Lex.getKind() == lltok::AttrGrpID);
748806
LocTy AttrGrpLoc = Lex.getLoc();
749807
unsigned VarID = Lex.getUIntVal();
808+
std::vector<unsigned> unused;
750809
Lex.Lex();
751810

752811
if (ParseToken(lltok::equal, "expected '=' here") ||
753812
ParseToken(lltok::kw_attributes, "expected 'attributes' keyword here") ||
754813
ParseToken(lltok::lbrace, "expected '{' here") ||
755-
ParseFnAttributeValuePairs(ForwardRefAttrBuilder[VarID], true) ||
814+
ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true) ||
756815
ParseToken(lltok::rbrace, "expected end of attribute group"))
757816
return true;
758817

759-
if (!ForwardRefAttrBuilder[VarID].hasAttributes())
818+
if (!NumberedAttrBuilders[VarID].hasAttributes())
760819
return Error(AttrGrpLoc, "attribute group has no attributes");
761820

762821
return false;
763822
}
764823

765824
/// ParseFnAttributeValuePairs
766825
/// ::= <attr> | <attr> '=' <value>
767-
bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, bool inAttrGrp) {
826+
bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
827+
std::vector<unsigned> &FwdRefAttrGrps,
828+
bool inAttrGrp) {
768829
bool HaveError = false;
769830

770831
B.clear();
@@ -779,6 +840,22 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, bool inAttrGrp) {
779840
// Finished.
780841
return false;
781842

843+
case lltok::AttrGrpID: {
844+
// Allow a function to reference an attribute group:
845+
//
846+
// define void @foo() #1 { ... }
847+
if (inAttrGrp)
848+
HaveError |=
849+
Error(Lex.getLoc(),
850+
"cannot have an attribute group reference in an attribute group");
851+
852+
unsigned AttrGrpNum = Lex.getUIntVal();
853+
if (inAttrGrp) break;
854+
855+
// Save the reference to the attribute group. We'll fill it in later.
856+
FwdRefAttrGrps.push_back(AttrGrpNum);
857+
break;
858+
}
782859
// Target-dependent attributes:
783860
case lltok::StringConstant: {
784861
std::string Attr = Lex.getStrVal();
@@ -2856,6 +2933,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
28562933
SmallVector<ArgInfo, 8> ArgList;
28572934
bool isVarArg;
28582935
AttrBuilder FuncAttrs;
2936+
std::vector<unsigned> FwdRefAttrGrps;
28592937
std::string Section;
28602938
unsigned Alignment;
28612939
std::string GC;
@@ -2865,7 +2943,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
28652943
if (ParseArgumentList(ArgList, isVarArg) ||
28662944
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
28672945
&UnnamedAddrLoc) ||
2868-
ParseFnAttributeValuePairs(FuncAttrs, false) ||
2946+
ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false) ||
28692947
(EatIfPresent(lltok::kw_section) &&
28702948
ParseStringConstant(Section)) ||
28712949
ParseOptionalAlignment(Alignment) ||
@@ -2965,6 +3043,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
29653043
Fn->setAlignment(Alignment);
29663044
Fn->setSection(Section);
29673045
if (!GC.empty()) Fn->setGC(GC.c_str());
3046+
ForwardRefAttrGroups[Fn] = FwdRefAttrGrps;
29683047

29693048
// Add all of the arguments we parsed to the function.
29703049
Function::arg_iterator ArgIt = Fn->arg_begin();
@@ -3384,6 +3463,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
33843463
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
33853464
LocTy CallLoc = Lex.getLoc();
33863465
AttrBuilder RetAttrs, FnAttrs;
3466+
std::vector<unsigned> FwdRefAttrGrps;
33873467
CallingConv::ID CC;
33883468
Type *RetType = 0;
33893469
LocTy RetTypeLoc;
@@ -3396,7 +3476,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
33963476
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
33973477
ParseValID(CalleeID) ||
33983478
ParseParameterList(ArgList, PFS) ||
3399-
ParseFnAttributeValuePairs(FnAttrs, false) ||
3479+
ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false) ||
34003480
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
34013481
ParseTypeAndBasicBlock(NormalBB, PFS) ||
34023482
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
@@ -3471,6 +3551,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
34713551
InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args);
34723552
II->setCallingConv(CC);
34733553
II->setAttributes(PAL);
3554+
ForwardRefAttrGroups[II] = FwdRefAttrGrps;
34743555
Inst = II;
34753556
return false;
34763557
}
@@ -3789,6 +3870,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
37893870
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
37903871
bool isTail) {
37913872
AttrBuilder RetAttrs, FnAttrs;
3873+
std::vector<unsigned> FwdRefAttrGrps;
37923874
CallingConv::ID CC;
37933875
Type *RetType = 0;
37943876
LocTy RetTypeLoc;
@@ -3802,7 +3884,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
38023884
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
38033885
ParseValID(CalleeID) ||
38043886
ParseParameterList(ArgList, PFS) ||
3805-
ParseFnAttributeValuePairs(FnAttrs, false))
3887+
ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false))
38063888
return true;
38073889

38083890
// If RetType is a non-function pointer type, then this is the short syntax
@@ -3874,6 +3956,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
38743956
CI->setTailCall(isTail);
38753957
CI->setCallingConv(CC);
38763958
CI->setAttributes(PAL);
3959+
ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
38773960
Inst = CI;
38783961
return false;
38793962
}

lib/AsmParser/LLParser.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ namespace llvm {
126126
ForwardRefBlockAddresses;
127127

128128
// Attribute builder reference information.
129-
std::map<unsigned, AttrBuilder> ForwardRefAttrBuilder;
129+
std::map<Value*, std::vector<unsigned> > ForwardRefAttrGroups;
130+
std::map<unsigned, AttrBuilder> NumberedAttrBuilders;
130131

131132
public:
132133
LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) :
@@ -239,7 +240,9 @@ namespace llvm {
239240
bool ParseMDNodeID(MDNode *&Result);
240241
bool ParseMDNodeID(MDNode *&Result, unsigned &SlotNo);
241242
bool ParseUnnamedAttrGrp();
242-
bool ParseFnAttributeValuePairs(AttrBuilder &B, bool inAttrGrp);
243+
bool ParseFnAttributeValuePairs(AttrBuilder &B,
244+
std::vector<unsigned> &FwdRefAttrGrps,
245+
bool inAttrGrp);
243246

244247
// Type Parsing.
245248
bool ParseType(Type *&Result, bool AllowVoid = false);

0 commit comments

Comments
 (0)