llvm.org GIT mirror llvm / 9f8d403
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230111 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 4 years ago
9 changed file(s) with 109 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
240240 case ')': return lltok::rparen;
241241 case ',': return lltok::comma;
242242 case '*': return lltok::star;
243 case '|': return lltok::bar;
243244 }
244245 }
245246
759760 DWKEYWORD(OP, DwarfOp);
760761 #undef DWKEYWORD
761762
763 if (Keyword.startswith("DIFlag")) {
764 StrVal.assign(Keyword.begin(), Keyword.end());
765 return lltok::DIFlag;
766 }
767
762768 // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
763769 // the CFE to avoid forcing it to deal with 64-bit numbers.
764770 if ((TokStart[0] == 'u' || TokStart[0] == 's') &&
1515 #include "llvm/IR/AutoUpgrade.h"
1616 #include "llvm/IR/CallingConv.h"
1717 #include "llvm/IR/Constants.h"
18 #include "llvm/IR/DebugInfo.h"
1819 #include "llvm/IR/DebugInfoMetadata.h"
1920 #include "llvm/IR/DerivedTypes.h"
2021 #include "llvm/IR/InlineAsm.h"
29562957 DwarfLangField() : MDUnsignedField(0, dwarf::DW_LANG_hi_user) {}
29572958 };
29582959
2960 struct DIFlagField : public MDUnsignedField {
2961 DIFlagField() : MDUnsignedField(0, UINT32_MAX) {}
2962 };
2963
29592964 struct MDSignedField : public MDFieldImpl {
29602965 int64_t Min;
29612966 int64_t Max;
30823087 assert(Encoding <= Result.Max && "Expected valid DWARF language");
30833088 Result.assign(Encoding);
30843089 Lex.Lex();
3090 return false;
3091 }
3092
3093 /// DIFlagField
3094 /// ::= uint32
3095 /// ::= DIFlagVector
3096 /// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic
3097 template <>
3098 bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
3099 assert(Result.Max == UINT32_MAX && "Expected only 32-bits");
3100
3101 // Parser for a single flag.
3102 auto parseFlag = [&](unsigned &Val) {
3103 if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned())
3104 return ParseUInt32(Val);
3105
3106 if (Lex.getKind() != lltok::DIFlag)
3107 return TokError("expected debug info flag");
3108
3109 Val = DIDescriptor::getFlag(Lex.getStrVal());
3110 if (!Val)
3111 return TokError(Twine("invalid debug info flag flag '") +
3112 Lex.getStrVal() + "'");
3113 Lex.Lex();
3114 return false;
3115 };
3116
3117 // Parse the flags and combine them together.
3118 unsigned Combined = 0;
3119 do {
3120 unsigned Val;
3121 if (parseFlag(Val))
3122 return true;
3123 Combined |= Val;
3124 } while (EatIfPresent(lltok::bar));
3125
3126 Result.assign(Combined);
30853127 return false;
30863128 }
30873129
33293371 OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
33303372 OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
33313373 OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
3332 OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
3374 OPTIONAL(flags, DIFlagField, ); \
33333375 OPTIONAL(extraData, MDField, );
33343376 PARSE_MD_FIELDS();
33353377 #undef VISIT_MD_FIELDS
33523394 OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
33533395 OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
33543396 OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
3355 OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
3397 OPTIONAL(flags, DIFlagField, ); \
33563398 OPTIONAL(elements, MDField, ); \
33573399 OPTIONAL(runtimeLang, DwarfLangField, ); \
33583400 OPTIONAL(vtableHolder, MDField, ); \
33713413
33723414 bool LLParser::ParseMDSubroutineType(MDNode *&Result, bool IsDistinct) {
33733415 #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
3374 OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
3416 OPTIONAL(flags, DIFlagField, ); \
33753417 REQUIRED(types, MDField, );
33763418 PARSE_MD_FIELDS();
33773419 #undef VISIT_MD_FIELDS
34483490 OPTIONAL(containingType, MDField, ); \
34493491 OPTIONAL(virtuality, DwarfVirtualityField, ); \
34503492 OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \
3451 OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
3493 OPTIONAL(flags, DIFlagField, ); \
34523494 OPTIONAL(isOptimized, MDBoolField, ); \
34533495 OPTIONAL(function, MDConstant, ); \
34543496 OPTIONAL(templateParams, MDField, ); \
35843626 OPTIONAL(line, LineField, ); \
35853627 OPTIONAL(type, MDField, ); \
35863628 OPTIONAL(arg, MDUnsignedField, (0, UINT8_MAX)); \
3587 OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
3629 OPTIONAL(flags, DIFlagField, ); \
35883630 OPTIONAL(inlinedAt, MDField, );
35893631 PARSE_MD_FIELDS();
35903632 #undef VISIT_MD_FIELDS
2828 less, greater, // < >
2929 lparen, rparen, // ( )
3030 exclaim, // !
31 bar, // |
3132
3233 kw_x,
3334 kw_true, kw_false,
202203 DwarfVirtuality, // DW_VIRTUALITY_foo
203204 DwarfLang, // DW_LANG_foo
204205 DwarfOp, // DW_OP_foo
206 DIFlag, // DIFlagFoo
205207
206208 // Type valued tokens (TyVal).
207209 Type,
12741274 namespace {
12751275 struct FieldSeparator {
12761276 bool Skip;
1277 FieldSeparator() : Skip(true) {}
1277 const char *Sep;
1278 FieldSeparator(const char *Sep = ", ") : Skip(true), Sep(Sep) {}
12781279 };
12791280 raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
12801281 if (FS.Skip) {
12811282 FS.Skip = false;
12821283 return OS;
12831284 }
1284 return OS << ", ";
1285 return OS << FS.Sep;
12851286 }
12861287 } // end namespace
12871288
13861387 Out << ")";
13871388 }
13881389
1390 static void writeDIFlags(raw_ostream &Out, unsigned Flags) {
1391 SmallVector SplitFlags;
1392 unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
1393
1394 FieldSeparator FS(" | ");
1395 for (unsigned F : SplitFlags) {
1396 const char *StringF = DIDescriptor::getFlagString(F);
1397 assert(StringF && "Expected valid flag");
1398 Out << FS << StringF;
1399 }
1400 if (Extra || SplitFlags.empty())
1401 Out << FS << Extra;
1402 }
1403
13891404 static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
13901405 TypePrinting *TypePrinter, SlotTracker *Machine,
13911406 const Module *Context) {
14131428 Out << FS << "align: " << N->getAlignInBits();
14141429 if (N->getOffsetInBits())
14151430 Out << FS << "offset: " << N->getOffsetInBits();
1416 if (N->getFlags())
1417 Out << FS << "flags: " << N->getFlags();
1431 if (auto Flags = N->getFlags()) {
1432 Out << FS << "flags: ";
1433 writeDIFlags(Out, Flags);
1434 }
14181435 if (N->getExtraData()) {
14191436 Out << FS << "extraData: ";
14201437 writeMetadataAsOperand(Out, N->getExtraData(), TypePrinter, Machine,
14531470 Out << FS << "align: " << N->getAlignInBits();
14541471 if (N->getOffsetInBits())
14551472 Out << FS << "offset: " << N->getOffsetInBits();
1456 if (N->getFlags())
1457 Out << FS << "flags: " << N->getFlags();
1473 if (auto Flags = N->getFlags()) {
1474 Out << FS << "flags: ";
1475 writeDIFlags(Out, Flags);
1476 }
14581477 if (N->getElements()) {
14591478 Out << FS << "elements: ";
14601479 writeMetadataAsOperand(Out, N->getElements(), TypePrinter, Machine,
14881507 SlotTracker *Machine, const Module *Context) {
14891508 Out << "!MDSubroutineType(";
14901509 FieldSeparator FS;
1491 if (N->getFlags())
1492 Out << FS << "flags: " << N->getFlags();
1510 if (auto Flags = N->getFlags()) {
1511 Out << FS << "flags: ";
1512 writeDIFlags(Out, Flags);
1513 }
14931514 Out << FS << "types: ";
14941515 writeMetadataAsOperand(Out, N->getTypeArray(), TypePrinter, Machine, Context);
14951516 Out << ")";
15931614 }
15941615 if (N->getVirtualIndex())
15951616 Out << FS << "virtualIndex: " << N->getVirtualIndex();
1596 if (N->getFlags())
1597 Out << FS << "flags: " << N->getFlags();
1617 if (auto Flags = N->getFlags()) {
1618 Out << FS << "flags: ";
1619 writeDIFlags(Out, Flags);
1620 }
15981621 Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
15991622 if (N->getFunction()) {
16001623 Out << FS << "function: ";
17631786 }
17641787 if (N->getTag() == dwarf::DW_TAG_arg_variable || N->getArg())
17651788 Out << FS << "arg: " << N->getArg();
1766 if (N->getFlags())
1767 Out << FS << "flags: " << N->getFlags();
1789 if (auto Flags = N->getFlags()) {
1790 Out << FS << "flags: ";
1791 writeDIFlags(Out, Flags);
1792 }
17681793 if (N->getInlinedAt()) {
17691794 Out << FS << "inlinedAt: ";
17701795 writeMetadataAsOperand(Out, N->getInlinedAt(), TypePrinter, Machine,
4040 !15 = !MDDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32)
4141
4242 ; CHECK-NEXT: !14 = !MDCompositeType(tag: DW_TAG_structure_type, name: "MyType", file: !10, line: 2, size: 32, align: 32, identifier: "MangledMyType")
43 ; CHECK-NEXT: !15 = distinct !MDCompositeType(tag: DW_TAG_structure_type, name: "Base", file: !10, line: 3, scope: !14, size: 128, align: 32, offset: 64, flags: 3, elements: !16, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !15, templateParams: !18, identifier: "MangledBase")
43 ; CHECK-NEXT: !15 = distinct !MDCompositeType(tag: DW_TAG_structure_type, name: "Base", file: !10, line: 3, scope: !14, size: 128, align: 32, offset: 64, flags: DIFlagPublic, elements: !16, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !15, templateParams: !18, identifier: "MangledBase")
4444 ; CHECK-NEXT: !16 = !{!17}
45 ; CHECK-NEXT: !17 = !MDDerivedType(tag: DW_TAG_member, name: "field", file: !10, line: 4, scope: !15, baseType: !6, size: 32, align: 32, offset: 32, flags: 3)
45 ; CHECK-NEXT: !17 = !MDDerivedType(tag: DW_TAG_member, name: "field", file: !10, line: 4, scope: !15, baseType: !6, size: 32, align: 32, offset: 32, flags: DIFlagPublic)
4646 ; CHECK-NEXT: !18 = !{!6}
47 ; CHECK-NEXT: !19 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Derived", file: !10, line: 3, scope: !14, baseType: !15, size: 128, align: 32, offset: 64, flags: 3, elements: !20, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !15, templateParams: !18, identifier: "MangledBase")
47 ; CHECK-NEXT: !19 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Derived", file: !10, line: 3, scope: !14, baseType: !15, size: 128, align: 32, offset: 64, flags: DIFlagPublic, elements: !20, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !15, templateParams: !18, identifier: "MangledBase")
4848 ; CHECK-NEXT: !20 = !{!21}
4949 ; CHECK-NEXT: !21 = !MDDerivedType(tag: DW_TAG_inheritance, scope: !19, baseType: !15)
5050 ; CHECK-NEXT: !22 = !MDDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !6, size: 32, align: 32, extraData: !15)
5151 ; CHECK-NEXT: !23 = !MDCompositeType(tag: DW_TAG_structure_type)
5252 ; CHECK-NEXT: !24 = !MDCompositeType(tag: DW_TAG_structure_type, runtimeLang: DW_LANG_Cobol85)
5353 !16 = !MDCompositeType(tag: DW_TAG_structure_type, name: "MyType", file: !12, line: 2, size: 32, align: 32, identifier: "MangledMyType")
54 !17 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Base", file: !12, line: 3, scope: !16, size: 128, align: 32, offset: 64, flags: 3, elements: !18, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !17, templateParams: !20, identifier: "MangledBase")
54 !17 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Base", file: !12, line: 3, scope: !16, size: 128, align: 32, offset: 64, flags: DIFlagPublic, elements: !18, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !17, templateParams: !20, identifier: "MangledBase")
5555 !18 = !{!19}
56 !19 = !MDDerivedType(tag: DW_TAG_member, name: "field", file: !12, line: 4, scope: !17, baseType: !7, size: 32, align: 32, offset: 32, flags: 3)
56 !19 = !MDDerivedType(tag: DW_TAG_member, name: "field", file: !12, line: 4, scope: !17, baseType: !7, size: 32, align: 32, offset: 32, flags: DIFlagPublic)
5757 !20 = !{!7}
58 !21 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Derived", file: !12, line: 3, scope: !16, baseType: !17, size: 128, align: 32, offset: 64, flags: 3, elements: !22, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !17, templateParams: !20, identifier: "MangledBase")
58 !21 = !MDCompositeType(tag: DW_TAG_structure_type, name: "Derived", file: !12, line: 3, scope: !16, baseType: !17, size: 128, align: 32, offset: 64, flags: DIFlagPublic, elements: !22, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !17, templateParams: !20, identifier: "MangledBase")
5959 !22 = !{!23}
6060 !23 = !MDDerivedType(tag: DW_TAG_inheritance, scope: !21, baseType: !17)
6161 !24 = !MDDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !7, size: 32, align: 32, extraData: !17)
6363 !26 = !MDCompositeType(tag: DW_TAG_structure_type, runtimeLang: 6)
6464
6565 ; !25 = !{!7, !7}
66 ; !26 = !MDSubroutineType(flags: 7, types: !25)
66 ; !26 = !MDSubroutineType(flags: DIFlagPublic | DIFlagStaticMember, types: !25)
6767 ; !27 = !MDSubroutineType(types: !25)
6868 !27 = !{!7, !7}
69 !28 = !MDSubroutineType(flags: 7, types: !27)
69 !28 = !MDSubroutineType(flags: DIFlagPublic | DIFlagStaticMember, types: !27)
7070 !29 = !MDSubroutineType(flags: 0, types: !27)
7171 !30 = !MDSubroutineType(types: !27)
0 ; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
11
2 ; CHECK: [[@LINE+1]]:33: error: missing required field 'types'
3 !29 = !MDSubroutineType(flags: 7)
2 ; CHECK: [[@LINE+1]]:65: error: missing required field 'types'
3 !29 = !MDSubroutineType(flags: DIFlagPublic | DIFlagStaticMember)
1111 !3 = distinct !{}
1212 !4 = distinct !{}
1313
14 ; CHECK: !5 = !MDLocalVariable(tag: DW_TAG_arg_variable, scope: !0, name: "foo", file: !2, line: 7, type: !3, arg: 3, flags: 8, inlinedAt: !4)
15 ; CHECK: !6 = !MDLocalVariable(tag: DW_TAG_auto_variable, scope: !0, name: "foo", file: !2, line: 7, type: !3, flags: 8, inlinedAt: !4)
14 ; CHECK: !5 = !MDLocalVariable(tag: DW_TAG_arg_variable, scope: !0, name: "foo", file: !2, line: 7, type: !3, arg: 3, flags: DIFlagArtificial, inlinedAt: !4)
15 ; CHECK: !6 = !MDLocalVariable(tag: DW_TAG_auto_variable, scope: !0, name: "foo", file: !2, line: 7, type: !3, flags: DIFlagArtificial, inlinedAt: !4)
1616 !5 = !MDLocalVariable(tag: DW_TAG_arg_variable, scope: !0, name: "foo",
1717 file: !2, line: 7, type: !3, arg: 3,
18 flags: 8, inlinedAt: !4)
18 flags: DIFlagArtificial, inlinedAt: !4)
1919 !6 = !MDLocalVariable(tag: DW_TAG_auto_variable, scope: !0, name: "foo",
20 file: !2, line: 7, type: !3, flags: 8, inlinedAt: !4)
20 file: !2, line: 7, type: !3, flags: DIFlagArtificial, inlinedAt: !4)
2121
2222 ; CHECK: !7 = !MDLocalVariable(tag: DW_TAG_arg_variable, scope: null, name: "", arg: 0)
2323 ; CHECK: !8 = !MDLocalVariable(tag: DW_TAG_auto_variable, scope: null, name: "")
1414 !6 = distinct !{}
1515 !7 = distinct !{}
1616
17 ; CHECK: !8 = !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoov", file: !2, line: 7, type: !3, isLocal: true, isDefinition: false, scopeLine: 8, containingType: !4, virtuality: DW_VIRTUALITY_pure_virtual, virtualIndex: 10, flags: 11, isOptimized: true, function: void ()* @_Z3foov, templateParams: !5, declaration: !6, variables: !7)
17 ; CHECK: !8 = !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoov", file: !2, line: 7, type: !3, isLocal: true, isDefinition: false, scopeLine: 8, containingType: !4, virtuality: DW_VIRTUALITY_pure_virtual, virtualIndex: 10, flags: DIFlagPrototyped, isOptimized: true, function: void ()* @_Z3foov, templateParams: !5, declaration: !6, variables: !7)
1818 !8 = !MDSubprogram(scope: !0, name: "foo", linkageName: "_Zfoov",
1919 file: !2, line: 7, type: !3, isLocal: true,
2020 isDefinition: false, scopeLine: 8, containingType: !4,
2121 virtuality: DW_VIRTUALITY_pure_virtual, virtualIndex: 10,
22 flags: 11, isOptimized: true, function: void ()* @_Z3foov,
22 flags: DIFlagPrototyped, isOptimized: true, function: void ()* @_Z3foov,
2323 templateParams: !5, declaration: !6, variables: !7)
2424
2525 ; CHECK: !9 = !MDSubprogram(scope: null, name: "bar", isLocal: false, isDefinition: true, isOptimized: false)
8181 syn match llvmConstant /\/
8282 syn match llvmConstant /\/
8383 syn match llvmConstant /\/
84 syn match llvmConstant /\/
8485
8586 " Syntax-highlight dejagnu test commands.
8687 syn match llvmSpecialComment /;\s*RUN:.*$/