forked from OSchip/llvm-project
Store defined macros in MCContext.
So that macros defined in inline assembly blocks are available to the whole file. This provides a consistent behavior with other assembly directives, since equations for example are already preserved between inline assembly blocks. PR: 36110 Patch by Roger! llvm-svn: 325139
This commit is contained in:
parent
3f60b0b3f4
commit
22c38a0748
|
@ -0,0 +1,38 @@
|
||||||
|
//===- MCAsmMacro.h - Assembly Macros ---------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_MC_MCASMMACRO_H
|
||||||
|
#define LLVM_MC_MCASMMACRO_H
|
||||||
|
|
||||||
|
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
struct MCAsmMacroParameter {
|
||||||
|
StringRef Name;
|
||||||
|
std::vector<AsmToken> Value;
|
||||||
|
bool Required = false;
|
||||||
|
bool Vararg = false;
|
||||||
|
|
||||||
|
MCAsmMacroParameter() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
|
||||||
|
struct MCAsmMacro {
|
||||||
|
StringRef Name;
|
||||||
|
StringRef Body;
|
||||||
|
MCAsmMacroParameters Parameters;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
|
||||||
|
: Name(N), Body(B), Parameters(std::move(P)) {}
|
||||||
|
};
|
||||||
|
}; // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
|
@ -18,6 +18,7 @@
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
|
#include "llvm/MC/MCAsmMacro.h"
|
||||||
#include "llvm/MC/MCDwarf.h"
|
#include "llvm/MC/MCDwarf.h"
|
||||||
#include "llvm/MC/MCSubtargetInfo.h"
|
#include "llvm/MC/MCSubtargetInfo.h"
|
||||||
#include "llvm/MC/SectionKind.h"
|
#include "llvm/MC/SectionKind.h"
|
||||||
|
@ -269,6 +270,9 @@ namespace llvm {
|
||||||
unsigned UniqueID,
|
unsigned UniqueID,
|
||||||
const MCSymbolELF *Associated);
|
const MCSymbolELF *Associated);
|
||||||
|
|
||||||
|
/// \brief Map of currently defined macros.
|
||||||
|
StringMap<MCAsmMacro> MacroMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
|
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
|
||||||
const MCObjectFileInfo *MOFI,
|
const MCObjectFileInfo *MOFI,
|
||||||
|
@ -620,6 +624,17 @@ namespace llvm {
|
||||||
// FIXME: We should really do something about that.
|
// FIXME: We should really do something about that.
|
||||||
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L,
|
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L,
|
||||||
const Twine &Msg);
|
const Twine &Msg);
|
||||||
|
|
||||||
|
const MCAsmMacro *lookupMacro(StringRef Name) {
|
||||||
|
StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name);
|
||||||
|
return (I == MacroMap.end()) ? nullptr : &I->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void defineMacro(StringRef Name, MCAsmMacro Macro) {
|
||||||
|
MacroMap.insert(std::make_pair(Name, std::move(Macro)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void undefineMacro(StringRef Name) { MacroMap.erase(Name); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
|
@ -84,27 +84,6 @@ namespace {
|
||||||
typedef std::vector<AsmToken> MCAsmMacroArgument;
|
typedef std::vector<AsmToken> MCAsmMacroArgument;
|
||||||
typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
|
typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
|
||||||
|
|
||||||
struct MCAsmMacroParameter {
|
|
||||||
StringRef Name;
|
|
||||||
MCAsmMacroArgument Value;
|
|
||||||
bool Required = false;
|
|
||||||
bool Vararg = false;
|
|
||||||
|
|
||||||
MCAsmMacroParameter() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
|
|
||||||
|
|
||||||
struct MCAsmMacro {
|
|
||||||
StringRef Name;
|
|
||||||
StringRef Body;
|
|
||||||
MCAsmMacroParameters Parameters;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
|
|
||||||
: Name(N), Body(B), Parameters(std::move(P)) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief Helper class for storing information about an active macro
|
/// \brief Helper class for storing information about an active macro
|
||||||
/// instantiation.
|
/// instantiation.
|
||||||
struct MacroInstantiation {
|
struct MacroInstantiation {
|
||||||
|
@ -165,9 +144,6 @@ private:
|
||||||
/// addDirectiveHandler.
|
/// addDirectiveHandler.
|
||||||
StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
|
StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
|
||||||
|
|
||||||
/// \brief Map of currently defined macros.
|
|
||||||
StringMap<MCAsmMacro> MacroMap;
|
|
||||||
|
|
||||||
/// \brief Stack of active macro instantiations.
|
/// \brief Stack of active macro instantiations.
|
||||||
std::vector<MacroInstantiation*> ActiveMacros;
|
std::vector<MacroInstantiation*> ActiveMacros;
|
||||||
|
|
||||||
|
@ -309,17 +285,6 @@ private:
|
||||||
/// \brief Control a flag in the parser that enables or disables macros.
|
/// \brief Control a flag in the parser that enables or disables macros.
|
||||||
void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
|
void setMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
|
||||||
|
|
||||||
/// \brief Lookup a previously defined macro.
|
|
||||||
/// \param Name Macro name.
|
|
||||||
/// \returns Pointer to macro. NULL if no such macro was defined.
|
|
||||||
const MCAsmMacro* lookupMacro(StringRef Name);
|
|
||||||
|
|
||||||
/// \brief Define a new macro with the given name and information.
|
|
||||||
void defineMacro(StringRef Name, MCAsmMacro Macro);
|
|
||||||
|
|
||||||
/// \brief Undefine a macro. If no such macro was defined, it's a no-op.
|
|
||||||
void undefineMacro(StringRef Name);
|
|
||||||
|
|
||||||
/// \brief Are we inside a macro instantiation?
|
/// \brief Are we inside a macro instantiation?
|
||||||
bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
|
bool isInsideMacroInstantiation() {return !ActiveMacros.empty();}
|
||||||
|
|
||||||
|
@ -1842,7 +1807,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
||||||
|
|
||||||
// If macros are enabled, check to see if this is a macro instantiation.
|
// If macros are enabled, check to see if this is a macro instantiation.
|
||||||
if (areMacrosEnabled())
|
if (areMacrosEnabled())
|
||||||
if (const MCAsmMacro *M = lookupMacro(IDVal)) {
|
if (const MCAsmMacro *M = getContext().lookupMacro(IDVal)) {
|
||||||
return handleMacroEntry(M, IDLoc);
|
return handleMacroEntry(M, IDLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2721,17 +2686,6 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
|
||||||
return TokError("too many positional arguments");
|
return TokError("too many positional arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) {
|
|
||||||
StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name);
|
|
||||||
return (I == MacroMap.end()) ? nullptr : &I->getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsmParser::defineMacro(StringRef Name, MCAsmMacro Macro) {
|
|
||||||
MacroMap.insert(std::make_pair(Name, std::move(Macro)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsmParser::undefineMacro(StringRef Name) { MacroMap.erase(Name); }
|
|
||||||
|
|
||||||
bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
|
bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
|
||||||
// Arbitrarily limit macro nesting depth (default matches 'as'). We can
|
// Arbitrarily limit macro nesting depth (default matches 'as'). We can
|
||||||
// eliminate this, although we should protect against infinite loops.
|
// eliminate this, although we should protect against infinite loops.
|
||||||
|
@ -4274,7 +4228,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
|
||||||
eatToEndOfStatement();
|
eatToEndOfStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lookupMacro(Name)) {
|
if (getContext().lookupMacro(Name)) {
|
||||||
return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
|
return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4282,7 +4236,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) {
|
||||||
const char *BodyEnd = EndToken.getLoc().getPointer();
|
const char *BodyEnd = EndToken.getLoc().getPointer();
|
||||||
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
|
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
|
||||||
checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
|
checkForBadMacro(DirectiveLoc, Name, Body, Parameters);
|
||||||
defineMacro(Name, MCAsmMacro(Name, Body, std::move(Parameters)));
|
getContext().defineMacro(Name, MCAsmMacro(Name, Body, std::move(Parameters)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4441,10 +4395,10 @@ bool AsmParser::parseDirectivePurgeMacro(SMLoc DirectiveLoc) {
|
||||||
"unexpected token in '.purgem' directive"))
|
"unexpected token in '.purgem' directive"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!lookupMacro(Name))
|
if (!getContext().lookupMacro(Name))
|
||||||
return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
|
return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
|
||||||
|
|
||||||
undefineMacro(Name);
|
getContext().undefineMacro(Name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
; RUN: not llc < %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
define void @test() {
|
||||||
|
call void asm sideeffect ".macro FOO\0A.endm", "~{dirflag},~{fpsr},~{flags}"() #1
|
||||||
|
call void asm sideeffect ".macro FOO\0A.endm", "~{dirflag},~{fpsr},~{flags}"() #1
|
||||||
|
; CHECK: error: macro 'FOO' is already defined
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue