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 {
MCContext(const MCContext&); // DO NOT IMPLEMENT
MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
public:
typedef StringMap<MCSymbol*, BumpPtrAllocator&> SymbolTable;
private:
/// The MCAsmInfo for this target.
const MCAsmInfo &MAI;
@ -52,7 +55,7 @@ namespace llvm {
BumpPtrAllocator Allocator;
/// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*, BumpPtrAllocator&> Symbols;
SymbolTable Symbols;
/// UsedNames - Keeps tracks of names that were used both for used declared
/// and artificial symbols.
@ -142,6 +145,14 @@ namespace llvm {
/// LookupSymbol - Get the symbol for \p Name, or null.
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

View File

@ -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)