mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
AsmParser/Bitcode: Add support for MDLocation
This adds assembly and bitcode support for `MDLocation`. The assembly side is rather big, since this is the first `MDNode` subclass (that isn't `MDTuple`). Part of PR21433. (If you're wondering where the mountains of testcase updates are, we don't need them until I update `DILocation` and `DebugLoc` to actually use this class.) llvm-svn: 225830
This commit is contained in:
parent
fb153e33c0
commit
85eaac222d
@ -2883,6 +2883,23 @@ attached to the ``add`` instruction using the ``!dbg`` identifier:
|
|||||||
More information about specific metadata nodes recognized by the
|
More information about specific metadata nodes recognized by the
|
||||||
optimizers and code generator is found below.
|
optimizers and code generator is found below.
|
||||||
|
|
||||||
|
Specialized Metadata Nodes
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Specialized metadata nodes are custom data structures in metadata (as opposed
|
||||||
|
to generic tuples). Their fields are labelled, and can be specified in any
|
||||||
|
order.
|
||||||
|
|
||||||
|
MDLocation
|
||||||
|
""""""""""
|
||||||
|
|
||||||
|
``MDLocation`` nodes represent source debug locations. The ``scope:`` field is
|
||||||
|
mandatory.
|
||||||
|
|
||||||
|
.. code-block:: llvm
|
||||||
|
|
||||||
|
!0 = !MDLocation(line: 2900, column: 42, scope: !1, inlinedAt: !2)
|
||||||
|
|
||||||
'``tbaa``' Metadata
|
'``tbaa``' Metadata
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ namespace bitc {
|
|||||||
METADATA_NAME = 4, // STRING: [values]
|
METADATA_NAME = 4, // STRING: [values]
|
||||||
METADATA_DISTINCT_NODE = 5, // DISTINCT_NODE: [n x md num]
|
METADATA_DISTINCT_NODE = 5, // DISTINCT_NODE: [n x md num]
|
||||||
METADATA_KIND = 6, // [n x [id, name]]
|
METADATA_KIND = 6, // [n x [id, name]]
|
||||||
// 7 is unused.
|
METADATA_LOCATION = 7, // [distinct, line, col, scope, inlined-at?]
|
||||||
METADATA_OLD_NODE = 8, // OLD_NODE: [n x (type num, value num)]
|
METADATA_OLD_NODE = 8, // OLD_NODE: [n x (type num, value num)]
|
||||||
METADATA_OLD_FN_NODE = 9, // OLD_FN_NODE: [n x (type num, value num)]
|
METADATA_OLD_FN_NODE = 9, // OLD_FN_NODE: [n x (type num, value num)]
|
||||||
METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
|
METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
|
||||||
|
@ -587,7 +587,10 @@ bool LLParser::ParseStandaloneMetadata() {
|
|||||||
return TokError("unexpected type in metadata definition");
|
return TokError("unexpected type in metadata definition");
|
||||||
|
|
||||||
bool IsDistinct = EatIfPresent(lltok::kw_distinct);
|
bool IsDistinct = EatIfPresent(lltok::kw_distinct);
|
||||||
if (ParseToken(lltok::exclaim, "Expected '!' here") ||
|
if (Lex.getKind() == lltok::MetadataVar) {
|
||||||
|
if (ParseSpecializedMDNode(Init, IsDistinct))
|
||||||
|
return true;
|
||||||
|
} else if (ParseToken(lltok::exclaim, "Expected '!' here") ||
|
||||||
ParseMDTuple(Init, IsDistinct))
|
ParseMDTuple(Init, IsDistinct))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -2902,7 +2905,11 @@ bool LLParser::ParseMDTuple(MDNode *&MD, bool IsDistinct) {
|
|||||||
/// MDNode:
|
/// MDNode:
|
||||||
/// ::= !{ ... }
|
/// ::= !{ ... }
|
||||||
/// ::= !7
|
/// ::= !7
|
||||||
|
/// ::= !MDLocation(...)
|
||||||
bool LLParser::ParseMDNode(MDNode *&N) {
|
bool LLParser::ParseMDNode(MDNode *&N) {
|
||||||
|
if (Lex.getKind() == lltok::MetadataVar)
|
||||||
|
return ParseSpecializedMDNode(N);
|
||||||
|
|
||||||
return ParseToken(lltok::exclaim, "expected '!' here") ||
|
return ParseToken(lltok::exclaim, "expected '!' here") ||
|
||||||
ParseMDNodeTail(N);
|
ParseMDNodeTail(N);
|
||||||
}
|
}
|
||||||
@ -2916,6 +2923,106 @@ bool LLParser::ParseMDNodeTail(MDNode *&N) {
|
|||||||
return ParseMDNodeID(N);
|
return ParseMDNodeID(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
|
||||||
|
MDUnsignedField<uint32_t> &Result) {
|
||||||
|
if (Result.Seen)
|
||||||
|
return Error(Loc,
|
||||||
|
"field '" + Name + "' cannot be specified more than once");
|
||||||
|
|
||||||
|
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
|
||||||
|
return TokError("expected unsigned integer");
|
||||||
|
uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(Result.Max + 1ull);
|
||||||
|
|
||||||
|
if (Val64 > Result.Max)
|
||||||
|
return TokError("value for '" + Name + "' too large, limit is " +
|
||||||
|
Twine(Result.Max));
|
||||||
|
Result.assign(Val64);
|
||||||
|
Lex.Lex();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
|
||||||
|
if (Result.Seen)
|
||||||
|
return Error(Loc,
|
||||||
|
"field '" + Name + "' cannot be specified more than once");
|
||||||
|
|
||||||
|
Metadata *MD;
|
||||||
|
if (ParseMetadata(MD, nullptr))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Result.assign(MD);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ParserTy>
|
||||||
|
bool LLParser::ParseMDFieldsImpl(ParserTy parseField) {
|
||||||
|
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
|
||||||
|
Lex.Lex();
|
||||||
|
|
||||||
|
if (ParseToken(lltok::lparen, "expected '(' here"))
|
||||||
|
return true;
|
||||||
|
if (EatIfPresent(lltok::rparen))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (Lex.getKind() != lltok::LabelStr)
|
||||||
|
return TokError("expected field label here");
|
||||||
|
|
||||||
|
if (parseField())
|
||||||
|
return true;
|
||||||
|
} while (EatIfPresent(lltok::comma));
|
||||||
|
|
||||||
|
return ParseToken(lltok::rparen, "expected ')' here");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LLParser::ParseSpecializedMDNode(MDNode *&N, bool IsDistinct) {
|
||||||
|
assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
|
||||||
|
#define DISPATCH_TO_PARSER(CLASS) \
|
||||||
|
if (Lex.getStrVal() == #CLASS) \
|
||||||
|
return Parse##CLASS(N, IsDistinct);
|
||||||
|
|
||||||
|
DISPATCH_TO_PARSER(MDLocation);
|
||||||
|
#undef DISPATCH_TO_PARSER
|
||||||
|
|
||||||
|
return TokError("expected metadata type");
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PARSE_MD_FIELD(NAME) \
|
||||||
|
do { \
|
||||||
|
if (Lex.getStrVal() == #NAME) { \
|
||||||
|
LocTy Loc = Lex.getLoc(); \
|
||||||
|
Lex.Lex(); \
|
||||||
|
if (ParseMDField(Loc, #NAME, NAME)) \
|
||||||
|
return true; \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/// ParseMDLocationFields:
|
||||||
|
/// ::= !MDLocation(line: 43, column: 8, scope: !5, inlinedAt: !6)
|
||||||
|
bool LLParser::ParseMDLocation(MDNode *&Result, bool IsDistinct) {
|
||||||
|
MDUnsignedField<uint32_t> line(0, ~0u >> 8);
|
||||||
|
MDUnsignedField<uint32_t> column(0, ~0u >> 24);
|
||||||
|
MDField scope;
|
||||||
|
MDField inlinedAt;
|
||||||
|
if (ParseMDFieldsImpl([&]() -> bool {
|
||||||
|
PARSE_MD_FIELD(line);
|
||||||
|
PARSE_MD_FIELD(column);
|
||||||
|
PARSE_MD_FIELD(scope);
|
||||||
|
PARSE_MD_FIELD(inlinedAt);
|
||||||
|
return TokError(Twine("invalid field '") + Lex.getStrVal() + "'");
|
||||||
|
}))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!scope.Seen)
|
||||||
|
return TokError("missing required field 'scope'");
|
||||||
|
|
||||||
|
auto get = (IsDistinct ? MDLocation::getDistinct : MDLocation::get);
|
||||||
|
Result = get(Context, line.Val, column.Val, scope.Val, inlinedAt.Val);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#undef PARSE_MD_FIELD
|
||||||
|
|
||||||
/// ParseMetadataAsValue
|
/// ParseMetadataAsValue
|
||||||
/// ::= metadata i32 %local
|
/// ::= metadata i32 %local
|
||||||
/// ::= metadata i32 @global
|
/// ::= metadata i32 @global
|
||||||
@ -2960,7 +3067,16 @@ bool LLParser::ParseValueAsMetadata(Metadata *&MD, PerFunctionState *PFS) {
|
|||||||
/// ::= !42
|
/// ::= !42
|
||||||
/// ::= !{...}
|
/// ::= !{...}
|
||||||
/// ::= !"string"
|
/// ::= !"string"
|
||||||
|
/// ::= !MDLocation(...)
|
||||||
bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
|
bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
|
||||||
|
if (Lex.getKind() == lltok::MetadataVar) {
|
||||||
|
MDNode *N;
|
||||||
|
if (ParseSpecializedMDNode(N))
|
||||||
|
return true;
|
||||||
|
MD = N;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// ValueAsMetadata:
|
// ValueAsMetadata:
|
||||||
// <type> <value>
|
// <type> <value>
|
||||||
if (Lex.getKind() != lltok::exclaim)
|
if (Lex.getKind() != lltok::exclaim)
|
||||||
|
@ -80,6 +80,31 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Structure to represent an optional metadata field.
|
||||||
|
template <class FieldTy> struct MDFieldImpl {
|
||||||
|
typedef MDFieldImpl ImplTy;
|
||||||
|
FieldTy Val;
|
||||||
|
bool Seen;
|
||||||
|
|
||||||
|
void assign(FieldTy Val) {
|
||||||
|
Seen = true;
|
||||||
|
this->Val = Val;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit MDFieldImpl(FieldTy Default) : Val(Default), Seen(false) {}
|
||||||
|
};
|
||||||
|
template <class NumTy> struct MDUnsignedField : public MDFieldImpl<NumTy> {
|
||||||
|
typedef typename MDUnsignedField::ImplTy ImplTy;
|
||||||
|
NumTy Max;
|
||||||
|
|
||||||
|
MDUnsignedField(NumTy Default = 0,
|
||||||
|
NumTy Max = std::numeric_limits<NumTy>::max())
|
||||||
|
: ImplTy(Default), Max(Max) {}
|
||||||
|
};
|
||||||
|
struct MDField : public MDFieldImpl<Metadata *> {
|
||||||
|
MDField() : ImplTy(nullptr) {}
|
||||||
|
};
|
||||||
|
|
||||||
class LLParser {
|
class LLParser {
|
||||||
public:
|
public:
|
||||||
typedef LLLexer::LocTy LocTy;
|
typedef LLLexer::LocTy LocTy;
|
||||||
@ -393,6 +418,13 @@ namespace llvm {
|
|||||||
bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs);
|
bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &MDs);
|
||||||
bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS);
|
bool ParseInstructionMetadata(Instruction *Inst, PerFunctionState *PFS);
|
||||||
|
|
||||||
|
bool ParseMDField(LocTy Loc, StringRef Name,
|
||||||
|
MDUnsignedField<uint32_t> &Result);
|
||||||
|
bool ParseMDField(LocTy Loc, StringRef Name, MDField &Result);
|
||||||
|
template <class ParserTy> bool ParseMDFieldsImpl(ParserTy parseField);
|
||||||
|
bool ParseSpecializedMDNode(MDNode *&N, bool IsDistinct = false);
|
||||||
|
bool ParseMDLocation(MDNode *&Result, bool IsDistinct);
|
||||||
|
|
||||||
// Function Parsing.
|
// Function Parsing.
|
||||||
struct ArgInfo {
|
struct ArgInfo {
|
||||||
LocTy Loc;
|
LocTy Loc;
|
||||||
|
@ -1267,6 +1267,20 @@ std::error_code BitcodeReader::ParseMetadata() {
|
|||||||
NextMDValueNo++);
|
NextMDValueNo++);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case bitc::METADATA_LOCATION: {
|
||||||
|
if (Record.size() != 5)
|
||||||
|
return Error("Invalid record");
|
||||||
|
|
||||||
|
auto get = Record[0] ? MDLocation::getDistinct : MDLocation::get;
|
||||||
|
unsigned Line = Record[1];
|
||||||
|
unsigned Column = Record[2];
|
||||||
|
MDNode *Scope = cast<MDNode>(MDValueList.getValueFwdRef(Record[3]));
|
||||||
|
Metadata *InlinedAt =
|
||||||
|
Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr;
|
||||||
|
MDValueList.AssignValue(get(Context, Line, Column, Scope, InlinedAt),
|
||||||
|
NextMDValueNo++);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case bitc::METADATA_STRING: {
|
case bitc::METADATA_STRING: {
|
||||||
std::string String(Record.begin(), Record.end());
|
std::string String(Record.begin(), Record.end());
|
||||||
llvm::UpgradeMDStringConstant(String);
|
llvm::UpgradeMDStringConstant(String);
|
||||||
|
@ -779,6 +779,25 @@ static void WriteMDNode(const MDNode *N,
|
|||||||
Record.clear();
|
Record.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WriteMDLocation(const MDLocation *N, const ValueEnumerator &VE,
|
||||||
|
BitstreamWriter &Stream,
|
||||||
|
SmallVectorImpl<uint64_t> &Record,
|
||||||
|
unsigned Abbrev) {
|
||||||
|
Record.push_back(N->isDistinct());
|
||||||
|
Record.push_back(N->getLine());
|
||||||
|
Record.push_back(N->getColumn());
|
||||||
|
Record.push_back(VE.getMetadataID(N->getScope()));
|
||||||
|
|
||||||
|
// Always emit the inlined-at location, even though it's optional.
|
||||||
|
if (Metadata *InlinedAt = N->getInlinedAt())
|
||||||
|
Record.push_back(VE.getMetadataID(InlinedAt) + 1);
|
||||||
|
else
|
||||||
|
Record.push_back(0);
|
||||||
|
|
||||||
|
Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev);
|
||||||
|
Record.clear();
|
||||||
|
}
|
||||||
|
|
||||||
static void WriteModuleMetadata(const Module *M,
|
static void WriteModuleMetadata(const Module *M,
|
||||||
const ValueEnumerator &VE,
|
const ValueEnumerator &VE,
|
||||||
BitstreamWriter &Stream) {
|
BitstreamWriter &Stream) {
|
||||||
@ -798,6 +817,22 @@ static void WriteModuleMetadata(const Module *M,
|
|||||||
MDSAbbrev = Stream.EmitAbbrev(Abbv);
|
MDSAbbrev = Stream.EmitAbbrev(Abbv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned LocAbbrev = 0;
|
||||||
|
if (VE.hasMDLocation()) {
|
||||||
|
// Abbrev for METADATA_LOCATION.
|
||||||
|
//
|
||||||
|
// Assume the column is usually under 128, and always output the inlined-at
|
||||||
|
// location (it's never more expensive than building an array size 1).
|
||||||
|
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION));
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
||||||
|
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
|
||||||
|
LocAbbrev = Stream.EmitAbbrev(Abbv);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned NameAbbrev = 0;
|
unsigned NameAbbrev = 0;
|
||||||
if (!M->named_metadata_empty()) {
|
if (!M->named_metadata_empty()) {
|
||||||
// Abbrev for METADATA_NAME.
|
// Abbrev for METADATA_NAME.
|
||||||
@ -810,6 +845,10 @@ static void WriteModuleMetadata(const Module *M,
|
|||||||
|
|
||||||
SmallVector<uint64_t, 64> Record;
|
SmallVector<uint64_t, 64> Record;
|
||||||
for (const Metadata *MD : MDs) {
|
for (const Metadata *MD : MDs) {
|
||||||
|
if (const MDLocation *Loc = dyn_cast<MDLocation>(MD)) {
|
||||||
|
WriteMDLocation(Loc, VE, Stream, Record, LocAbbrev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (const MDNode *N = dyn_cast<MDNode>(MD)) {
|
if (const MDNode *N = dyn_cast<MDNode>(MD)) {
|
||||||
WriteMDNode(N, VE, Stream, Record);
|
WriteMDNode(N, VE, Stream, Record);
|
||||||
continue;
|
continue;
|
||||||
|
@ -282,7 +282,8 @@ static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) {
|
|||||||
return V.first->getType()->isIntOrIntVectorTy();
|
return V.first->getType()->isIntOrIntVectorTy();
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueEnumerator::ValueEnumerator(const Module &M) : HasMDString(false) {
|
ValueEnumerator::ValueEnumerator(const Module &M)
|
||||||
|
: HasMDString(false), HasMDLocation(false) {
|
||||||
if (shouldPreserveBitcodeUseListOrder())
|
if (shouldPreserveBitcodeUseListOrder())
|
||||||
UseListOrders = predictUseListOrder(M);
|
UseListOrders = predictUseListOrder(M);
|
||||||
|
|
||||||
@ -547,6 +548,7 @@ void ValueEnumerator::EnumerateMetadata(const Metadata *MD) {
|
|||||||
EnumerateValue(C->getValue());
|
EnumerateValue(C->getValue());
|
||||||
|
|
||||||
HasMDString |= isa<MDString>(MD);
|
HasMDString |= isa<MDString>(MD);
|
||||||
|
HasMDLocation |= isa<MDLocation>(MD);
|
||||||
|
|
||||||
// Replace the dummy ID inserted above with the correct one. MDValueMap may
|
// Replace the dummy ID inserted above with the correct one. MDValueMap may
|
||||||
// have changed by inserting operands, so we need a fresh lookup here.
|
// have changed by inserting operands, so we need a fresh lookup here.
|
||||||
|
@ -65,6 +65,7 @@ private:
|
|||||||
typedef DenseMap<const Metadata *, unsigned> MetadataMapType;
|
typedef DenseMap<const Metadata *, unsigned> MetadataMapType;
|
||||||
MetadataMapType MDValueMap;
|
MetadataMapType MDValueMap;
|
||||||
bool HasMDString;
|
bool HasMDString;
|
||||||
|
bool HasMDLocation;
|
||||||
|
|
||||||
typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
|
typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType;
|
||||||
AttributeGroupMapType AttributeGroupMap;
|
AttributeGroupMapType AttributeGroupMap;
|
||||||
@ -111,6 +112,7 @@ public:
|
|||||||
unsigned getMetadataID(const Metadata *V) const;
|
unsigned getMetadataID(const Metadata *V) const;
|
||||||
|
|
||||||
bool hasMDString() const { return HasMDString; }
|
bool hasMDString() const { return HasMDString; }
|
||||||
|
bool hasMDLocation() const { return HasMDLocation; }
|
||||||
|
|
||||||
unsigned getTypeID(Type *T) const {
|
unsigned getTypeID(Type *T) const {
|
||||||
TypeMapType::const_iterator I = TypeMap.find(T);
|
TypeMapType::const_iterator I = TypeMap.find(T);
|
||||||
|
4
test/Assembler/invalid-mdlocation-field-bad.ll
Normal file
4
test/Assembler/invalid-mdlocation-field-bad.ll
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: <stdin>:[[@LINE+1]]:18: error: invalid field 'bad'
|
||||||
|
!0 = !MDLocation(bad: 0)
|
6
test/Assembler/invalid-mdlocation-field-twice.ll
Normal file
6
test/Assembler/invalid-mdlocation-field-twice.ll
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
!0 = !{}
|
||||||
|
|
||||||
|
; CHECK: <stdin>:[[@LINE+1]]:38: error: field 'line' cannot be specified more than once
|
||||||
|
!1 = !MDLocation(line: 3, scope: !0, line: 3)
|
9
test/Assembler/invalid-mdlocation-overflow-column.ll
Normal file
9
test/Assembler/invalid-mdlocation-overflow-column.ll
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
!0 = !{}
|
||||||
|
|
||||||
|
; CHECK-NOT: error
|
||||||
|
!1 = !MDLocation(column: 255, scope: !0)
|
||||||
|
|
||||||
|
; CHECK: <stdin>:[[@LINE+1]]:26: error: value for 'column' too large, limit is 255
|
||||||
|
!2 = !MDLocation(column: 256, scope: !0)
|
9
test/Assembler/invalid-mdlocation-overflow-line.ll
Normal file
9
test/Assembler/invalid-mdlocation-overflow-line.ll
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
!0 = !{}
|
||||||
|
|
||||||
|
; CHECK-NOT: error
|
||||||
|
!1 = !MDLocation(line: 16777215, scope: !0)
|
||||||
|
|
||||||
|
; CHECK: <stdin>:[[@LINE+1]]:24: error: value for 'line' too large, limit is 16777215
|
||||||
|
!2 = !MDLocation(line: 16777216, scope: !0)
|
4
test/Assembler/invalid-specialized-mdnode.ll
Normal file
4
test/Assembler/invalid-specialized-mdnode.ll
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; CHECK: <stdin>:[[@LINE+1]]:6: error: expected metadata type
|
||||||
|
!0 = !Invalid(field: 0)
|
20
test/Assembler/mdlocation.ll
Normal file
20
test/Assembler/mdlocation.ll
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||||
|
; RUN: verify-uselistorder %s
|
||||||
|
|
||||||
|
; CHECK: !named = !{!0, !1, !1, !2, !2, !3, !3}
|
||||||
|
!named = !{!0, !1, !2, !3, !4, !5, !6}
|
||||||
|
|
||||||
|
; CHECK: !0 = !{}
|
||||||
|
!0 = !{}
|
||||||
|
|
||||||
|
; CHECK-NEXT: !1 = !MDLocation(line: 3, column: 7, scope: !0)
|
||||||
|
!1 = !MDLocation(line: 3, column: 7, scope: !0)
|
||||||
|
!2 = !MDLocation(scope: !0, column: 7, line: 3)
|
||||||
|
|
||||||
|
; CHECK-NEXT: !2 = !MDLocation(line: 3, column: 7, scope: !0, inlinedAt: !1)
|
||||||
|
!3 = !MDLocation(scope: !0, inlinedAt: !1, column: 7, line: 3)
|
||||||
|
!4 = !MDLocation(column: 7, line: 3, scope: !0, inlinedAt: !1)
|
||||||
|
|
||||||
|
; CHECK-NEXT: !3 = !MDLocation(scope: !0)
|
||||||
|
!5 = !MDLocation(scope: !0)
|
||||||
|
!6 = !MDLocation(scope: !0, column: 0, line: 0)
|
@ -62,7 +62,7 @@ syn keyword llvmKeyword uselistorder_bb
|
|||||||
syn keyword llvmError getresult begin end
|
syn keyword llvmError getresult begin end
|
||||||
|
|
||||||
" Misc syntax.
|
" Misc syntax.
|
||||||
syn match llvmNoName /[%@]\d\+\>/
|
syn match llvmNoName /[%@!]\d\+\>/
|
||||||
syn match llvmNumber /-\?\<\d\+\>/
|
syn match llvmNumber /-\?\<\d\+\>/
|
||||||
syn match llvmFloat /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/
|
syn match llvmFloat /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/
|
||||||
syn match llvmFloat /\<0x\x\+\>/
|
syn match llvmFloat /\<0x\x\+\>/
|
||||||
@ -73,6 +73,11 @@ syn region llvmString start=/"/ skip=/\\"/ end=/"/
|
|||||||
syn match llvmLabel /[-a-zA-Z$._][-a-zA-Z$._0-9]*:/
|
syn match llvmLabel /[-a-zA-Z$._][-a-zA-Z$._0-9]*:/
|
||||||
syn match llvmIdentifier /[%@][-a-zA-Z$._][-a-zA-Z$._0-9]*/
|
syn match llvmIdentifier /[%@][-a-zA-Z$._][-a-zA-Z$._0-9]*/
|
||||||
|
|
||||||
|
" Named metadata and specialized metadata keywords.
|
||||||
|
syn match llvmIdentifier /![-a-zA-Z$._][-a-zA-Z$._0-9]*\ze\s*$/
|
||||||
|
syn match llvmIdentifier /![-a-zA-Z$._][-a-zA-Z$._0-9]*\ze\s*[=!]/
|
||||||
|
syn match llvmType /!\zs\a\+\ze\s*(/
|
||||||
|
|
||||||
" Syntax-highlight dejagnu test commands.
|
" Syntax-highlight dejagnu test commands.
|
||||||
syn match llvmSpecialComment /;\s*RUN:.*$/
|
syn match llvmSpecialComment /;\s*RUN:.*$/
|
||||||
syn match llvmSpecialComment /;\s*PR\d*\s*$/
|
syn match llvmSpecialComment /;\s*PR\d*\s*$/
|
||||||
|
Loading…
Reference in New Issue
Block a user