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.

llvm-svn: 133071
This commit is contained in:
Jim Grosbach 2011-06-15 18:33:28 +00:00
parent 471a22febc
commit c7e6b8fed5
2 changed files with 41 additions and 5 deletions

View File

@ -39,6 +39,9 @@ namespace llvm {
class MCContext { class MCContext {
MCContext(const MCContext&); // DO NOT IMPLEMENT MCContext(const MCContext&); // DO NOT IMPLEMENT
MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
public:
typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
private:
/// The MCAsmInfo for this target. /// The MCAsmInfo for this target.
const MCAsmInfo &MAI; const MCAsmInfo &MAI;
@ -52,7 +55,7 @@ namespace llvm {
BumpPtrAllocator Allocator; BumpPtrAllocator Allocator;
/// Symbols - Bindings of names to symbols. /// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*, BumpPtrAllocator&> Symbols; SymbolTable Symbols;
/// UsedNames - Keeps tracks of names that were used both for used declared /// UsedNames - Keeps tracks of names that were used both for used declared
/// and artificial symbols. /// and artificial symbols.
@ -142,6 +145,14 @@ namespace llvm {
/// LookupSymbol - Get the symbol for \p Name, or null. /// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const; MCSymbol *LookupSymbol(StringRef Name) const;
/// getSymbols - Get a reference for the symbol table for clients that
/// want to, for example, iterate over all symbols. 'const' because we
/// still want any modifications to the table itself to use the MCContext
/// APIs.
const SymbolTable &getSymbols() const {
return Symbols;
}
/// @} /// @}
/// @name Section Management /// @name Section Management

View File

@ -84,6 +84,7 @@ private:
AsmLexer Lexer; AsmLexer Lexer;
MCContext &Ctx; MCContext &Ctx;
MCStreamer &Out; MCStreamer &Out;
const MCAsmInfo &MAI;
SourceMgr &SrcMgr; SourceMgr &SrcMgr;
MCAsmParserExtension *GenericParser; MCAsmParserExtension *GenericParser;
MCAsmParserExtension *PlatformParser; MCAsmParserExtension *PlatformParser;
@ -135,7 +136,7 @@ public:
virtual MCContext &getContext() { return Ctx; } virtual MCContext &getContext() { return Ctx; }
virtual MCStreamer &getStreamer() { return Out; } 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); virtual bool Error(SMLoc L, const Twine &Msg);
const AsmToken &Lex(); const AsmToken &Lex();
@ -160,8 +161,9 @@ private:
void HandleMacroExit(); void HandleMacroExit();
void PrintMacroInstantiations(); void PrintMacroInstantiations();
void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type) const { void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
SrcMgr.PrintMessage(Loc, Msg, Type); bool ShowLine = true) const {
SrcMgr.PrintMessage(Loc, Msg, Type, ShowLine);
} }
/// EnterIncludeFile - Enter the specified file. This returns true on failure. /// 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, AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx,
MCStreamer &_Out, const MCAsmInfo &_MAI) 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), GenericParser(new GenericAsmParser), PlatformParser(0),
CurBuffer(0), MacrosEnabled(true) { CurBuffer(0), MacrosEnabled(true) {
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); 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"); 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 // Finalize the output stream if there are no errors and if the client wants
// us to. // us to.
if (!HadError && !NoFinalize) if (!HadError && !NoFinalize)