@@ -146,6 +146,9 @@ class AsmParser : public MCAsmParser {
146
146
// / \brief List of bodies of anonymous macros.
147
147
std::deque<MCAsmMacro> MacroLikeBodies;
148
148
149
+ // / \brief List of forward directional labels for diagnosis at the end.
150
+ SmallVector<std::pair<SMLoc, MCSymbol *>, 4 > DirectionalLabels;
151
+
149
152
// / Boolean tracking whether macro substitution is enabled.
150
153
unsigned MacrosEnabledFlag : 1 ;
151
154
@@ -683,18 +686,28 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
683
686
// Targets that don't do subsections via symbols may not want this, though,
684
687
// so conservatively exclude them. Only do this if we're finalizing, though,
685
688
// as otherwise we won't necessarilly have seen everything yet.
686
- if (!NoFinalize && MAI.hasSubsectionsViaSymbols ()) {
687
- for (const auto &TableEntry : getContext ().getSymbols ()) {
688
- MCSymbol *Sym = TableEntry.getValue ();
689
- // Variable symbols may not be marked as defined, so check those
690
- // explicitly. If we know it's a variable, we have a definition for
691
- // the purposes of this check.
692
- if (Sym->isTemporary () && !Sym->isVariable () && !Sym->isDefined ())
693
- // FIXME: We would really like to refer back to where the symbol was
694
- // first referenced for a source location. We need to add something
695
- // to track that. Currently, we just point to the end of the file.
696
- return Error (getLexer ().getLoc (), " assembler local symbol '" +
697
- Sym->getName () + " ' not defined" );
689
+ if (!NoFinalize) {
690
+ if (MAI.hasSubsectionsViaSymbols ()) {
691
+ for (const auto &TableEntry : getContext ().getSymbols ()) {
692
+ MCSymbol *Sym = TableEntry.getValue ();
693
+ // Variable symbols may not be marked as defined, so check those
694
+ // explicitly. If we know it's a variable, we have a definition for
695
+ // the purposes of this check.
696
+ if (Sym->isTemporary () && !Sym->isVariable () && !Sym->isDefined ())
697
+ // FIXME: We would really like to refer back to where the symbol was
698
+ // first referenced for a source location. We need to add something
699
+ // to track that. Currently, we just point to the end of the file.
700
+ HadError |=
701
+ Error (getLexer ().getLoc (), " assembler local symbol '" +
702
+ Sym->getName () + " ' not defined" );
703
+ }
704
+ }
705
+
706
+ // Temporary symbols like the ones for directional jumps don't go in the
707
+ // symbol table. They also need to be diagnosed in all (final) cases.
708
+ for (std::pair<SMLoc, MCSymbol *> &LocSym : DirectionalLabels) {
709
+ if (LocSym.second ->isUndefined ())
710
+ HadError |= Error (LocSym.first , " directional label undefined" );
698
711
}
699
712
}
700
713
@@ -904,7 +917,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
904
917
Ctx.getDirectionalLocalSymbol (IntVal, IDVal == " b" );
905
918
Res = MCSymbolRefExpr::create (Sym, Variant, getContext ());
906
919
if (IDVal == " b" && Sym->isUndefined ())
907
- return Error (Loc, " invalid reference to undefined symbol" );
920
+ return Error (Loc, " directional label undefined" );
921
+ DirectionalLabels.push_back (std::make_pair (Loc, Sym));
908
922
EndLoc = Lexer.getTok ().getEndLoc ();
909
923
Lex (); // Eat identifier.
910
924
}
0 commit comments