llvm.org GIT mirror llvm / b50df4a
TableGen: Keep track of superclass reference ranges. def foo : bar; ~~~ This allows us to produce more precise diagnostics about a certain superclass, and even provide fixits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172085 91177308-0d34-0410-b5e6-96231b3b80d8 Jordan Rose 7 years ago
4 changed file(s) with 57 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
13861386 SmallVector Locs;
13871387 std::vector TemplateArgs;
13881388 std::vector Values;
1389 std::vector*> SuperClasses;
1389 std::vector *> SuperClasses;
1390 std::vector SuperClassRanges;
13901391
13911392 // Tracks Record instances. Not owned by Record.
13921393 RecordKeeper &TrackedRecords;
14181419 Record(const Record &O) :
14191420 ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
14201421 Values(O.Values), SuperClasses(O.SuperClasses),
1421 TrackedRecords(O.TrackedRecords), TheInit(O.TheInit),
1422 IsAnonymous(O.IsAnonymous) { }
1422 SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords),
1423 TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { }
14231424
14241425 ~Record() {}
14251426
14501451 }
14511452 const std::vector &getValues() const { return Values; }
14521453 const std::vector &getSuperClasses() const { return SuperClasses; }
1454 ArrayRef getSuperClassRanges() const { return SuperClassRanges; }
14531455
14541456 bool isTemplateArg(Init *Name) const {
14551457 for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
15241526 return false;
15251527 }
15261528
1527 void addSuperClass(Record *R) {
1529 void addSuperClass(Record *R, SMRange Range) {
15281530 assert(!isSubClassOf(R) && "Already subclassing record!");
15291531 SuperClasses.push_back(R);
1532 SuperClassRanges.push_back(Range);
15301533 }
15311534
15321535 /// resolveReferences - If there are any field references that refer to fields
2525
2626 namespace llvm {
2727 struct SubClassReference {
28 SMLoc RefLoc;
28 SMRange RefRange;
2929 Record *Rec;
3030 std::vector TemplateArgs;
3131 SubClassReference() : Rec(0) {}
3434 };
3535
3636 struct SubMultiClassReference {
37 SMLoc RefLoc;
37 SMRange RefRange;
3838 MultiClass *MC;
3939 std::vector TemplateArgs;
4040 SubMultiClassReference() : MC(0) {}
149149 // Add all of the values in the subclass into the current class.
150150 const std::vector &Vals = SC->getValues();
151151 for (unsigned i = 0, e = Vals.size(); i != e; ++i)
152 if (AddValue(CurRec, SubClass.RefLoc, Vals[i]))
152 if (AddValue(CurRec, SubClass.RefRange.Start, Vals[i]))
153153 return true;
154154
155155 const std::vector &TArgs = SC->getTemplateArgs();
156156
157157 // Ensure that an appropriate number of template arguments are specified.
158158 if (TArgs.size() < SubClass.TemplateArgs.size())
159 return Error(SubClass.RefLoc, "More template args specified than expected");
159 return Error(SubClass.RefRange.Start,
160 "More template args specified than expected");
160161
161162 // Loop over all of the template arguments, setting them to the specified
162163 // value or leaving them as the default if necessary.
163164 for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
164165 if (i < SubClass.TemplateArgs.size()) {
165166 // If a value is specified for this template arg, set it now.
166 if (SetValue(CurRec, SubClass.RefLoc, TArgs[i], std::vector(),
167 SubClass.TemplateArgs[i]))
167 if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i],
168 std::vector(), SubClass.TemplateArgs[i]))
168169 return true;
169170
170171 // Resolve it next.
174175 CurRec->removeValue(TArgs[i]);
175176
176177 } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
177 return Error(SubClass.RefLoc,"Value not specified for template argument #"
178 return Error(SubClass.RefRange.Start,
179 "Value not specified for template argument #"
178180 + utostr(i) + " (" + TArgs[i]->getAsUnquotedString()
179181 + ") of subclass '" + SC->getNameInitAsString() + "'!");
180182 }
183185 // Since everything went well, we can now set the "superclass" list for the
184186 // current record.
185187 const std::vector &SCs = SC->getSuperClasses();
188 ArrayRef SCRanges = SC->getSuperClassRanges();
186189 for (unsigned i = 0, e = SCs.size(); i != e; ++i) {
187190 if (CurRec->isSubClassOf(SCs[i]))
188 return Error(SubClass.RefLoc,
191 return Error(SubClass.RefRange.Start,
189192 "Already subclass of '" + SCs[i]->getName() + "'!\n");
190 CurRec->addSuperClass(SCs[i]);
193 CurRec->addSuperClass(SCs[i], SCRanges[i]);
191194 }
192195
193196 if (CurRec->isSubClassOf(SC))
194 return Error(SubClass.RefLoc,
197 return Error(SubClass.RefRange.Start,
195198 "Already subclass of '" + SC->getName() + "'!\n");
196 CurRec->addSuperClass(SC);
199 CurRec->addSuperClass(SC, SubClass.RefRange);
197200 return false;
198201 }
199202
210213 // Add all of the values in the subclass into the current class.
211214 const std::vector &SMCVals = SMC->Rec.getValues();
212215 for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
213 if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
216 if (AddValue(CurRec, SubMultiClass.RefRange.Start, SMCVals[i]))
214217 return true;
215218
216219 int newDefStart = CurMC->DefPrototypes.size();
225228
226229 // Add all of the values in the superclass into the current def.
227230 for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
228 if (AddValue(NewDef, SubMultiClass.RefLoc, MCVals[i]))
231 if (AddValue(NewDef, SubMultiClass.RefRange.Start, MCVals[i]))
229232 return true;
230233
231234 CurMC->DefPrototypes.push_back(NewDef);
236239 // Ensure that an appropriate number of template arguments are
237240 // specified.
238241 if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
239 return Error(SubMultiClass.RefLoc,
242 return Error(SubMultiClass.RefRange.Start,
240243 "More template args specified than expected");
241244
242245 // Loop over all of the template arguments, setting them to the specified
245248 if (i < SubMultiClass.TemplateArgs.size()) {
246249 // If a value is specified for this template arg, set it in the
247250 // superclass now.
248 if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i],
251 if (SetValue(CurRec, SubMultiClass.RefRange.Start, SMCTArgs[i],
249252 std::vector(),
250253 SubMultiClass.TemplateArgs[i]))
251254 return true;
265268 ++j) {
266269 Record *Def = *j;
267270
268 if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i],
271 if (SetValue(Def, SubMultiClass.RefRange.Start, SMCTArgs[i],
269272 std::vector(),
270273 SubMultiClass.TemplateArgs[i]))
271274 return true;
277280 Def->removeValue(SMCTArgs[i]);
278281 }
279282 } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
280 return Error(SubMultiClass.RefLoc,
283 return Error(SubMultiClass.RefRange.Start,
281284 "Value not specified for template argument #"
282285 + utostr(i) + " (" + SMCTArgs[i]->getAsUnquotedString()
283286 + ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!");
463466 SubClassReference TGParser::
464467 ParseSubClassReference(Record *CurRec, bool isDefm) {
465468 SubClassReference Result;
466 Result.RefLoc = Lex.getLoc();
469 Result.RefRange.Start = Lex.getLoc();
467470
468471 if (isDefm) {
469472 if (MultiClass *MC = ParseMultiClassID())
474477 if (Result.Rec == 0) return Result;
475478
476479 // If there is no template arg list, we're done.
477 if (Lex.getCode() != tgtok::less)
480 if (Lex.getCode() != tgtok::less) {
481 Result.RefRange.End = Lex.getLoc();
478482 return Result;
483 }
479484 Lex.Lex(); // Eat the '<'
480485
481486 if (Lex.getCode() == tgtok::greater) {
496501 return Result;
497502 }
498503 Lex.Lex();
504 Result.RefRange.End = Lex.getLoc();
499505
500506 return Result;
501507 }
510516 SubMultiClassReference TGParser::
511517 ParseSubMultiClassReference(MultiClass *CurMC) {
512518 SubMultiClassReference Result;
513 Result.RefLoc = Lex.getLoc();
519 Result.RefRange.Start = Lex.getLoc();
514520
515521 Result.MC = ParseMultiClassID();
516522 if (Result.MC == 0) return Result;
517523
518524 // If there is no template arg list, we're done.
519 if (Lex.getCode() != tgtok::less)
525 if (Lex.getCode() != tgtok::less) {
526 Result.RefRange.End = Lex.getLoc();
520527 return Result;
528 }
521529 Lex.Lex(); // Eat the '<'
522530
523531 if (Lex.getCode() == tgtok::greater) {
538546 return Result;
539547 }
540548 Lex.Lex();
549 Result.RefRange.End = Lex.getLoc();
541550
542551 return Result;
543552 }
11981207 return 0;
11991208 }
12001209 Lex.Lex(); // eat the '>'
1210 SMLoc EndLoc = Lex.getLoc();
12011211
12021212 // Create the new record, set it as CurRec temporarily.
12031213 static unsigned AnonCounter = 0;
12061216 Records,
12071217 /*IsAnonymous=*/true);
12081218 SubClassReference SCRef;
1209 SCRef.RefLoc = NameLoc;
1219 SCRef.RefRange = SMRange(NameLoc, EndLoc);
12101220 SCRef.Rec = Class;
12111221 SCRef.TemplateArgs = ValueList;
12121222 // Add info about the subclass to NewRec.
22452255 InstantiateMulticlassDef(MultiClass &MC,
22462256 Record *DefProto,
22472257 Init *DefmPrefix,
2248 SMLoc DefmPrefixLoc) {
2258 SMRange DefmPrefixRange) {
22492259 // We need to preserve DefProto so it can be reused for later
22502260 // instantiations, so create a new Record to inherit from it.
22512261
22752285 }
22762286
22772287 // Make a trail of SMLocs from the multiclass instantiations.
2278 SmallVector Locs(1, DefmPrefixLoc);
2288 SmallVector Locs(1, DefmPrefixRange.Start);
22792289 Locs.append(DefProto->getLoc().begin(), DefProto->getLoc().end());
22802290 Record *CurRec = new Record(DefName, Locs, Records, IsAnonymous);
22812291
22822292 SubClassReference Ref;
2283 Ref.RefLoc = DefmPrefixLoc;
2293 Ref.RefRange = DefmPrefixRange;
22842294 Ref.Rec = DefProto;
22852295 AddSubClass(CurRec, Ref);
22862296
22872297 // Set the value for NAME. We don't resolve references to it 'til later,
22882298 // though, so that uses in nested multiclass names don't get
22892299 // confused.
2290 if (SetValue(CurRec, Ref.RefLoc, "NAME", std::vector(),
2300 if (SetValue(CurRec, Ref.RefRange.Start, "NAME", std::vector(),
22912301 DefmPrefix)) {
2292 Error(DefmPrefixLoc, "Could not resolve "
2302 Error(DefmPrefixRange.Start, "Could not resolve "
22932303 + CurRec->getNameInitAsString() + ":NAME to '"
22942304 + DefmPrefix->getAsUnquotedString() + "'");
22952305 return 0;
23202330
23212331 // Ensure redefinition doesn't happen.
23222332 if (Records.getDef(CurRec->getNameInitAsString())) {
2323 Error(DefmPrefixLoc, "def '" + CurRec->getNameInitAsString() +
2333 Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() +
23242334 "' already defined, instantiating defm with subdef '" +
23252335 DefProto->getNameInitAsString() + "'");
23262336 return 0;
24062416 ///
24072417 bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
24082418 assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
2409
2419 SMLoc DefmLoc = Lex.getLoc();
24102420 Init *DefmPrefix = 0;
24112421
24122422 if (Lex.Lex() == tgtok::Id) { // eat the defm.
24132423 DefmPrefix = ParseObjectName(CurMultiClass);
24142424 }
24152425
2416 SMLoc DefmPrefixLoc = Lex.getLoc();
2426 SMLoc DefmPrefixEndLoc = Lex.getLoc();
24172427 if (Lex.getCode() != tgtok::colon)
24182428 return TokError("expected ':' after defm identifier");
24192429
24492459 for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
24502460 Record *DefProto = MC->DefPrototypes[i];
24512461
2452 Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix, DefmPrefixLoc);
2462 Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix,
2463 SMRange(DefmLoc,
2464 DefmPrefixEndLoc));
24532465 if (!CurRec)
24542466 return true;
24552467
2456 if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc, SubClassLoc,
2468 if (ResolveMulticlassDefArgs(*MC, CurRec, DefmLoc, SubClassLoc,
24572469 TArgs, TemplateVals, true/*Delete args*/))
24582470 return Error(SubClassLoc, "could not instantiate def");
24592471
2460 if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc))
2472 if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmLoc))
24612473 return Error(SubClassLoc, "could not instantiate def");
24622474
24632475 NewRecDefs.push_back(CurRec);
133133 Record *InstantiateMulticlassDef(MultiClass &MC,
134134 Record *DefProto,
135135 Init *DefmPrefix,
136 SMLoc DefmPrefixLoc);
136 SMRange DefmPrefixRange);
137137 bool ResolveMulticlassDefArgs(MultiClass &MC,
138138 Record *DefProto,
139139 SMLoc DefmPrefixLoc,
635635 Elts.insert(NewReg);
636636
637637 // Copy Proto super-classes.
638 for (unsigned i = 0, e = Proto->getSuperClasses().size(); i != e; ++i)
639 NewReg->addSuperClass(Proto->getSuperClasses()[i]);
638 ArrayRef Supers = Proto->getSuperClasses();
639 ArrayRef Ranges = Proto->getSuperClassRanges();
640 for (unsigned i = 0, e = Supers.size(); i != e; ++i)
641 NewReg->addSuperClass(Supers[i], Ranges[i]);
640642
641643 // Copy Proto fields.
642644 for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {