summaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2012-08-08 06:30:30 +0000
committerBill Wendling <isanbard@gmail.com>2012-08-08 06:30:30 +0000
commitef920552d4fb0959097f1c165cfc81c69db19934 (patch)
treea1f589492e274e09eb1aa6dcdac1b0fb4a27eb86 /lib/MC
parentd43b5c97cff06d7840b974ca84fa0639d2567968 (diff)
downloadllvm-ef920552d4fb0959097f1c165cfc81c69db19934.tar.gz
llvm-ef920552d4fb0959097f1c165cfc81c69db19934.tar.bz2
llvm-ef920552d4fb0959097f1c165cfc81c69db19934.tar.xz
Add `.pushsection', `.popsection', and `.previous' directives to Darwin ASM.
There are situations where inline ASM may want to change the section -- for instance, to create a variable in the .data section. However, it cannot do this without (potentially) restoring to the wrong section. E.g.: asm volatile (".section __DATA, __data\n\t" ".globl _fnord\n\t" "_fnord: .quad 1f\n\t" ".text\n\t" "1:" :::); This may be wrong if this is inlined into a function that has a "section" attribute. The user should use `.pushsection' and `.popsection' here instead. The addition of `.previous' is added for completeness. <rdar://problem/12048387> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161477 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp41
1 files changed, 39 insertions, 2 deletions
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 5662fea86c..18033d05eb 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -50,6 +50,9 @@ public:
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
+ AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
".secure_log_unique");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
@@ -112,6 +115,9 @@ public:
bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
bool ParseDirectiveLsym(StringRef, SMLoc);
bool ParseDirectiveSection(StringRef, SMLoc);
+ bool ParseDirectivePushSection(StringRef, SMLoc);
+ bool ParseDirectivePopSection(StringRef, SMLoc);
+ bool ParseDirectivePrevious(StringRef, SMLoc);
bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
@@ -297,7 +303,7 @@ public:
};
-}
+} // end anonymous namespace
bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
const char *Section,
@@ -457,6 +463,37 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
return false;
}
+/// ParseDirectivePushSection:
+/// ::= .pushsection identifier (',' identifier)*
+bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
+ getStreamer().PushSection();
+
+ if (ParseDirectiveSection(S, Loc)) {
+ getStreamer().PopSection();
+ return true;
+ }
+
+ return false;
+}
+
+/// ParseDirectivePopSection:
+/// ::= .popsection
+bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
+ if (!getStreamer().PopSection())
+ return TokError(".popsection without corresponding .pushsection");
+ return false;
+}
+
+/// ParseDirectivePrevious:
+/// ::= .previous
+bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
+ const MCSection *PreviousSection = getStreamer().getPreviousSection();
+ if (PreviousSection == NULL)
+ return TokError(".previous without corresponding .section");
+ getStreamer().SwitchSection(PreviousSection);
+ return false;
+}
+
/// ParseDirectiveSecureLogUnique
/// ::= .secure_log_unique ... message ...
bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
@@ -707,4 +744,4 @@ MCAsmParserExtension *createDarwinAsmParser() {
return new DarwinAsmParser;
}
-}
+} // end llvm namespace