summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-21 01:02:18 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-02-21 01:02:18 +0000
commit70ab3d2af667a97523d2ab4f03b0d2f978693f47 (patch)
tree919c0b0fac56a22397ceba0d966be3dd0aec310f /llvm/lib
parentc32f3faae9c7128dec280b8274de31400df5e704 (diff)
downloadbcm5719-llvm-70ab3d2af667a97523d2ab4f03b0d2f978693f47.tar.gz
bcm5719-llvm-70ab3d2af667a97523d2ab4f03b0d2f978693f47.zip
AsmParser/Writer: Handle symbolic constants in DI 'flags:'
Parse (and write) symbolic constants in debug info `flags:` fields. This prevents a readability (and CHECK-ability) regression with the new debug info hierarchy. Old (well, current) assembly, with pretty-printing: !{!"...\\0016387", ...} ; ... [public] [rvalue reference] Flags field without this change: !MDDerivedType(flags: 16387, ...) Flags field with this change: !MDDerivedType(flags: DIFlagPublic | DIFlagRValueReference, ...) As discussed in the review thread, this isn't a final state. Most of these flags correspond to `DW_AT_` symbolic constants, and we might eventually want to support arbitrary attributes in some form. However, as it stands now, some of the flags correspond to other concepts (like `FlagStaticMember`); until things are refactored this is the simplest way to move forward without regressing assembly. llvm-svn: 230111
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp6
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp52
-rw-r--r--llvm/lib/AsmParser/LLToken.h2
-rw-r--r--llvm/lib/IR/AsmWriter.cpp49
4 files changed, 92 insertions, 17 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 656b1692182..3bf090a4b33 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -241,6 +241,7 @@ lltok::Kind LLLexer::LexToken() {
case ')': return lltok::rparen;
case ',': return lltok::comma;
case '*': return lltok::star;
+ case '|': return lltok::bar;
}
}
@@ -760,6 +761,11 @@ lltok::Kind LLLexer::LexIdentifier() {
DWKEYWORD(OP, DwarfOp);
#undef DWKEYWORD
+ if (Keyword.startswith("DIFlag")) {
+ StrVal.assign(Keyword.begin(), Keyword.end());
+ return lltok::DIFlag;
+ }
+
// Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
// the CFE to avoid forcing it to deal with 64-bit numbers.
if ((TokStart[0] == 'u' || TokStart[0] == 's') &&
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 28b8d22e579..fa4653b30bc 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -16,6 +16,7 @@
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
@@ -2957,6 +2958,10 @@ struct DwarfLangField : public MDUnsignedField {
DwarfLangField() : MDUnsignedField(0, dwarf::DW_LANG_hi_user) {}
};
+struct DIFlagField : public MDUnsignedField {
+ DIFlagField() : MDUnsignedField(0, UINT32_MAX) {}
+};
+
struct MDSignedField : public MDFieldImpl<int64_t> {
int64_t Min;
int64_t Max;
@@ -3086,6 +3091,43 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
return false;
}
+/// DIFlagField
+/// ::= uint32
+/// ::= DIFlagVector
+/// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
+ assert(Result.Max == UINT32_MAX && "Expected only 32-bits");
+
+ // Parser for a single flag.
+ auto parseFlag = [&](unsigned &Val) {
+ if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned())
+ return ParseUInt32(Val);
+
+ if (Lex.getKind() != lltok::DIFlag)
+ return TokError("expected debug info flag");
+
+ Val = DIDescriptor::getFlag(Lex.getStrVal());
+ if (!Val)
+ return TokError(Twine("invalid debug info flag flag '") +
+ Lex.getStrVal() + "'");
+ Lex.Lex();
+ return false;
+ };
+
+ // Parse the flags and combine them together.
+ unsigned Combined = 0;
+ do {
+ unsigned Val;
+ if (parseFlag(Val))
+ return true;
+ Combined |= Val;
+ } while (EatIfPresent(lltok::bar));
+
+ Result.assign(Combined);
+ return false;
+}
+
template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
MDSignedField &Result) {
@@ -3330,7 +3372,7 @@ bool LLParser::ParseMDDerivedType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(extraData, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -3353,7 +3395,7 @@ bool LLParser::ParseMDCompositeType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(elements, MDField, ); \
OPTIONAL(runtimeLang, DwarfLangField, ); \
OPTIONAL(vtableHolder, MDField, ); \
@@ -3372,7 +3414,7 @@ bool LLParser::ParseMDCompositeType(MDNode *&Result, bool IsDistinct) {
bool LLParser::ParseMDSubroutineType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
REQUIRED(types, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -3449,7 +3491,7 @@ bool LLParser::ParseMDSubprogram(MDNode *&Result, bool IsDistinct) {
OPTIONAL(containingType, MDField, ); \
OPTIONAL(virtuality, DwarfVirtualityField, ); \
OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(isOptimized, MDBoolField, ); \
OPTIONAL(function, MDConstant, ); \
OPTIONAL(templateParams, MDField, ); \
@@ -3585,7 +3627,7 @@ bool LLParser::ParseMDLocalVariable(MDNode *&Result, bool IsDistinct) {
OPTIONAL(line, LineField, ); \
OPTIONAL(type, MDField, ); \
OPTIONAL(arg, MDUnsignedField, (0, UINT8_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(inlinedAt, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index 57218dafbb9..a7aa17c37cc 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -29,6 +29,7 @@ namespace lltok {
less, greater, // < >
lparen, rparen, // ( )
exclaim, // !
+ bar, // |
kw_x,
kw_true, kw_false,
@@ -203,6 +204,7 @@ namespace lltok {
DwarfVirtuality, // DW_VIRTUALITY_foo
DwarfLang, // DW_LANG_foo
DwarfOp, // DW_OP_foo
+ DIFlag, // DIFlagFoo
// Type valued tokens (TyVal).
Type,
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 47a1b5512a9..104ad4f0be3 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1275,14 +1275,15 @@ static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
namespace {
struct FieldSeparator {
bool Skip;
- FieldSeparator() : Skip(true) {}
+ const char *Sep;
+ FieldSeparator(const char *Sep = ", ") : Skip(true), Sep(Sep) {}
};
raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
if (FS.Skip) {
FS.Skip = false;
return OS;
}
- return OS << ", ";
+ return OS << FS.Sep;
}
} // end namespace
@@ -1387,6 +1388,20 @@ static void writeMDBasicType(raw_ostream &Out, const MDBasicType *N,
Out << ")";
}
+static void writeDIFlags(raw_ostream &Out, unsigned Flags) {
+ SmallVector<unsigned, 8> SplitFlags;
+ unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
+
+ FieldSeparator FS(" | ");
+ for (unsigned F : SplitFlags) {
+ const char *StringF = DIDescriptor::getFlagString(F);
+ assert(StringF && "Expected valid flag");
+ Out << FS << StringF;
+ }
+ if (Extra || SplitFlags.empty())
+ Out << FS << Extra;
+}
+
static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
@@ -1414,8 +1429,10 @@ static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
Out << FS << "align: " << N->getAlignInBits();
if (N->getOffsetInBits())
Out << FS << "offset: " << N->getOffsetInBits();
- if (N->getFlags())
- Out << FS << "flags: " << N->getFlags();
+ if (auto Flags = N->getFlags()) {
+ Out << FS << "flags: ";
+ writeDIFlags(Out, Flags);
+ }
if (N->getExtraData()) {
Out << FS << "extraData: ";
writeMetadataAsOperand(Out, N->getExtraData(), TypePrinter, Machine,
@@ -1454,8 +1471,10 @@ static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
Out << FS << "align: " << N->getAlignInBits();
if (N->getOffsetInBits())
Out << FS << "offset: " << N->getOffsetInBits();
- if (N->getFlags())
- Out << FS << "flags: " << N->getFlags();
+ if (auto Flags = N->getFlags()) {
+ Out << FS << "flags: ";
+ writeDIFlags(Out, Flags);
+ }
if (N->getElements()) {
Out << FS << "elements: ";
writeMetadataAsOperand(Out, N->getElements(), TypePrinter, Machine,
@@ -1489,8 +1508,10 @@ static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
SlotTracker *Machine, const Module *Context) {
Out << "!MDSubroutineType(";
FieldSeparator FS;
- if (N->getFlags())
- Out << FS << "flags: " << N->getFlags();
+ if (auto Flags = N->getFlags()) {
+ Out << FS << "flags: ";
+ writeDIFlags(Out, Flags);
+ }
Out << FS << "types: ";
writeMetadataAsOperand(Out, N->getTypeArray(), TypePrinter, Machine, Context);
Out << ")";
@@ -1594,8 +1615,10 @@ static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
}
if (N->getVirtualIndex())
Out << FS << "virtualIndex: " << N->getVirtualIndex();
- if (N->getFlags())
- Out << FS << "flags: " << N->getFlags();
+ if (auto Flags = N->getFlags()) {
+ Out << FS << "flags: ";
+ writeDIFlags(Out, Flags);
+ }
Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
if (N->getFunction()) {
Out << FS << "function: ";
@@ -1764,8 +1787,10 @@ static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N,
}
if (N->getTag() == dwarf::DW_TAG_arg_variable || N->getArg())
Out << FS << "arg: " << N->getArg();
- if (N->getFlags())
- Out << FS << "flags: " << N->getFlags();
+ if (auto Flags = N->getFlags()) {
+ Out << FS << "flags: ";
+ writeDIFlags(Out, Flags);
+ }
if (N->getInlinedAt()) {
Out << FS << "inlinedAt: ";
writeMetadataAsOperand(Out, N->getInlinedAt(), TypePrinter, Machine,
OpenPOWER on IntegriCloud