@@ -65,6 +65,64 @@ bool LLParser::ValidateEndOfModule() {
65
65
ForwardRefInstMetadata.clear ();
66
66
}
67
67
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
+ }
68
126
69
127
// If there are entries in ForwardRefBlockAddresses at this point, they are
70
128
// references after the function was defined. Resolve those now.
@@ -747,24 +805,27 @@ bool LLParser::ParseUnnamedAttrGrp() {
747
805
assert (Lex.getKind () == lltok::AttrGrpID);
748
806
LocTy AttrGrpLoc = Lex.getLoc ();
749
807
unsigned VarID = Lex.getUIntVal ();
808
+ std::vector<unsigned > unused;
750
809
Lex.Lex ();
751
810
752
811
if (ParseToken (lltok::equal, " expected '=' here" ) ||
753
812
ParseToken (lltok::kw_attributes, " expected 'attributes' keyword here" ) ||
754
813
ParseToken (lltok::lbrace, " expected '{' here" ) ||
755
- ParseFnAttributeValuePairs (ForwardRefAttrBuilder [VarID], true ) ||
814
+ ParseFnAttributeValuePairs (NumberedAttrBuilders [VarID], unused , true ) ||
756
815
ParseToken (lltok::rbrace, " expected end of attribute group" ))
757
816
return true ;
758
817
759
- if (!ForwardRefAttrBuilder [VarID].hasAttributes ())
818
+ if (!NumberedAttrBuilders [VarID].hasAttributes ())
760
819
return Error (AttrGrpLoc, " attribute group has no attributes" );
761
820
762
821
return false ;
763
822
}
764
823
765
824
// / ParseFnAttributeValuePairs
766
825
// / ::= <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) {
768
829
bool HaveError = false ;
769
830
770
831
B.clear ();
@@ -779,6 +840,22 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, bool inAttrGrp) {
779
840
// Finished.
780
841
return false ;
781
842
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
+ }
782
859
// Target-dependent attributes:
783
860
case lltok::StringConstant: {
784
861
std::string Attr = Lex.getStrVal ();
@@ -2856,6 +2933,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
2856
2933
SmallVector<ArgInfo, 8 > ArgList;
2857
2934
bool isVarArg;
2858
2935
AttrBuilder FuncAttrs;
2936
+ std::vector<unsigned > FwdRefAttrGrps;
2859
2937
std::string Section;
2860
2938
unsigned Alignment;
2861
2939
std::string GC;
@@ -2865,7 +2943,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
2865
2943
if (ParseArgumentList (ArgList, isVarArg) ||
2866
2944
ParseOptionalToken (lltok::kw_unnamed_addr, UnnamedAddr,
2867
2945
&UnnamedAddrLoc) ||
2868
- ParseFnAttributeValuePairs (FuncAttrs, false ) ||
2946
+ ParseFnAttributeValuePairs (FuncAttrs, FwdRefAttrGrps, false ) ||
2869
2947
(EatIfPresent (lltok::kw_section) &&
2870
2948
ParseStringConstant (Section)) ||
2871
2949
ParseOptionalAlignment (Alignment) ||
@@ -2965,6 +3043,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
2965
3043
Fn->setAlignment (Alignment);
2966
3044
Fn->setSection (Section);
2967
3045
if (!GC.empty ()) Fn->setGC (GC.c_str ());
3046
+ ForwardRefAttrGroups[Fn] = FwdRefAttrGrps;
2968
3047
2969
3048
// Add all of the arguments we parsed to the function.
2970
3049
Function::arg_iterator ArgIt = Fn->arg_begin ();
@@ -3384,6 +3463,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
3384
3463
bool LLParser::ParseInvoke (Instruction *&Inst, PerFunctionState &PFS) {
3385
3464
LocTy CallLoc = Lex.getLoc ();
3386
3465
AttrBuilder RetAttrs, FnAttrs;
3466
+ std::vector<unsigned > FwdRefAttrGrps;
3387
3467
CallingConv::ID CC;
3388
3468
Type *RetType = 0 ;
3389
3469
LocTy RetTypeLoc;
@@ -3396,7 +3476,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
3396
3476
ParseType (RetType, RetTypeLoc, true /* void allowed*/ ) ||
3397
3477
ParseValID (CalleeID) ||
3398
3478
ParseParameterList (ArgList, PFS) ||
3399
- ParseFnAttributeValuePairs (FnAttrs, false ) ||
3479
+ ParseFnAttributeValuePairs (FnAttrs, FwdRefAttrGrps, false ) ||
3400
3480
ParseToken (lltok::kw_to, " expected 'to' in invoke" ) ||
3401
3481
ParseTypeAndBasicBlock (NormalBB, PFS) ||
3402
3482
ParseToken (lltok::kw_unwind, " expected 'unwind' in invoke" ) ||
@@ -3471,6 +3551,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
3471
3551
InvokeInst *II = InvokeInst::Create (Callee, NormalBB, UnwindBB, Args);
3472
3552
II->setCallingConv (CC);
3473
3553
II->setAttributes (PAL);
3554
+ ForwardRefAttrGroups[II] = FwdRefAttrGrps;
3474
3555
Inst = II;
3475
3556
return false ;
3476
3557
}
@@ -3789,6 +3870,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
3789
3870
bool LLParser::ParseCall (Instruction *&Inst, PerFunctionState &PFS,
3790
3871
bool isTail) {
3791
3872
AttrBuilder RetAttrs, FnAttrs;
3873
+ std::vector<unsigned > FwdRefAttrGrps;
3792
3874
CallingConv::ID CC;
3793
3875
Type *RetType = 0 ;
3794
3876
LocTy RetTypeLoc;
@@ -3802,7 +3884,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
3802
3884
ParseType (RetType, RetTypeLoc, true /* void allowed*/ ) ||
3803
3885
ParseValID (CalleeID) ||
3804
3886
ParseParameterList (ArgList, PFS) ||
3805
- ParseFnAttributeValuePairs (FnAttrs, false ))
3887
+ ParseFnAttributeValuePairs (FnAttrs, FwdRefAttrGrps, false ))
3806
3888
return true ;
3807
3889
3808
3890
// 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,
3874
3956
CI->setTailCall (isTail);
3875
3957
CI->setCallingConv (CC);
3876
3958
CI->setAttributes (PAL);
3959
+ ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
3877
3960
Inst = CI;
3878
3961
return false ;
3879
3962
}
0 commit comments