summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser/AsmParser.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-06-15 18:33:28 +0000
committerJim Grosbach <grosbach@apple.com>2011-06-15 18:33:28 +0000
commite82b8eeaa2d36ee52690ae19bca9735629b6003e (patch)
tree89b7d51d52090f5fc5485c76297c220228b9abbb /lib/MC/MCParser/AsmParser.cpp
parent2f473cee286e9c71ee8e7d6b1c46b05f2aed7336 (diff)
downloadllvm-e82b8eeaa2d36ee52690ae19bca9735629b6003e.tar.gz
llvm-e82b8eeaa2d36ee52690ae19bca9735629b6003e.tar.bz2
llvm-e82b8eeaa2d36ee52690ae19bca9735629b6003e.tar.xz
Diagnostic for undefined assembler local symbols.
Re-apply 133010, with fixes for inline assembler. Original commit message: "When an assembler local symbol is used but not defined in a module, a Darwin assembler wants to issue a diagnostic to that effect." Added fix to only perform the check when finalizing, as otherwise we're not done and undefined symbols may simply not have been encountered yet. Passes "make check" and a self-host check on Darwin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133071 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp33
1 files changed, 29 insertions, 4 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 4f55cea7bc..bbd6635108 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -84,6 +84,7 @@ private:
AsmLexer Lexer;
MCContext &Ctx;
MCStreamer &Out;
+ const MCAsmInfo &MAI;
SourceMgr &SrcMgr;
MCAsmParserExtension *GenericParser;
MCAsmParserExtension *PlatformParser;
@@ -135,7 +136,7 @@ public:
virtual MCContext &getContext() { return Ctx; }
virtual MCStreamer &getStreamer() { return Out; }
- virtual bool Warning(SMLoc L, const Twine &Meg);
+ virtual bool Warning(SMLoc L, const Twine &Msg);
virtual bool Error(SMLoc L, const Twine &Msg);
const AsmToken &Lex();
@@ -160,8 +161,9 @@ private:
void HandleMacroExit();
void PrintMacroInstantiations();
- void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type) const {
- SrcMgr.PrintMessage(Loc, Msg, Type);
+ void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
+ bool ShowLine = true) const {
+ SrcMgr.PrintMessage(Loc, Msg, Type, ShowLine);
}
/// EnterIncludeFile - Enter the specified file. This returns true on failure.
@@ -337,7 +339,7 @@ enum { DEFAULT_ADDRSPACE = 0 };
AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx,
MCStreamer &_Out, const MCAsmInfo &_MAI)
- : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM),
+ : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
GenericParser(new GenericAsmParser), PlatformParser(0),
CurBuffer(0), MacrosEnabled(true) {
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
@@ -466,6 +468,29 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
TokError("unassigned file number: " + Twine(i) + " for .file directives");
}
+ // Check to see that all assembler local symbols were actually defined.
+ // Targets that don't do subsections via symbols may not want this, though,
+ // so conservatively exclude them. Only do this if we're finalizing, though,
+ // as otherwise we won't necessarilly have seen everything yet.
+ if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) {
+ const MCContext::SymbolTable &Symbols = getContext().getSymbols();
+ for (MCContext::SymbolTable::const_iterator i = Symbols.begin(),
+ e = Symbols.end();
+ i != e; ++i) {
+ MCSymbol *Sym = i->getValue();
+ // Variable symbols may not be marked as defined, so check those
+ // explicitly. If we know it's a variable, we have a definition for
+ // the purposes of this check.
+ if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
+ // FIXME: We would really like to refer back to where the symbol was
+ // first referenced for a source location. We need to add something
+ // to track that. Currently, we just point to the end of the file.
+ PrintMessage(getLexer().getLoc(), "assembler local symbol '" +
+ Sym->getName() + "' not defined", "error", false);
+ }
+ }
+
+
// Finalize the output stream if there are no errors and if the client wants
// us to.
if (!HadError && !NoFinalize)