ParseType(Ty, TyLoc) ||
ParseToken(lltok::exclaim, "Expected '!' here") ||
ParseToken(lltok::lbrace, "Expected '{' here") ||
- ParseMDNodeVector(Elts) ||
+ ParseMDNodeVector(Elts, NULL) ||
ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
/// type implied. For example, if we parse "4" we don't know what integer type
/// it has. The value will later be combined with its type and checked for
/// sanity.
-bool LLParser::ParseValID(ValID &ID) {
+bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ID.Loc = Lex.getLoc();
switch (Lex.getKind()) {
default: return TokError("expected value token");
if (EatIfPresent(lltok::lbrace)) {
SmallVector<Value*, 16> Elts;
- if (ParseMDNodeVector(Elts) ||
+ if (ParseMDNodeVector(Elts, PFS) ||
ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
}
/// ConvertGlobalOrMetadataValIDToValue - Apply a type to a ValID to get a fully
-/// resolved constant or metadata value.
+/// resolved constant, metadata, or function-local value
bool LLParser::ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
- Value *&V) {
+ Value *&V,
+ PerFunctionState *PFS) {
switch (ID.Kind) {
case ValID::t_MDNode:
if (!Ty->isMetadataTy())
return Error(ID.Loc, "metadata value must have metadata type");
V = ID.MDStringVal;
return false;
+ case ValID::t_LocalID:
+ case ValID::t_LocalName:
+ if (!PFS)
+ return Error(ID.Loc, "invalid use of function-local name");
+ if (ConvertValIDToValue(Ty, ID, V, *PFS)) return true;
+ return false;
default:
Constant *C;
if (ConvertGlobalValIDToValue(Ty, ID, C)) return true;
return false;
}
default:
- return ConvertGlobalOrMetadataValIDToValue(Ty, ID, V);
+ return ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, &PFS);
}
return V == 0;
bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
V = 0;
ValID ID;
- return ParseValID(ID) ||
+ return ParseValID(ID, &PFS) ||
ConvertValIDToValue(Ty, ID, V, PFS);
}
/// ::= Element (',' Element)*
/// Element
/// ::= 'null' | TypeAndValue
-bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts) {
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
+ PerFunctionState *PFS) {
do {
// Null is a special case since it is typeless.
if (EatIfPresent(lltok::kw_null)) {
Value *V = 0;
PATypeHolder Ty(Type::getVoidTy(Context));
ValID ID;
- if (ParseType(Ty) || ParseValID(ID) ||
- ConvertGlobalOrMetadataValIDToValue(Ty, ID, V))
+ if (ParseType(Ty) || ParseValID(ID, PFS) ||
+ ConvertGlobalOrMetadataValIDToValue(Ty, ID, V, PFS))
return true;
Elts.push_back(V);
bool ParseFunctionType(PATypeHolder &Result);
PATypeHolder HandleUpRefs(const Type *Ty);
- // Constants.
- bool ParseValID(ValID &ID);
- bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V);
- bool ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
- Value *&V);
- bool ParseGlobalValue(const Type *Ty, Constant *&V);
- bool ParseGlobalTypeAndValue(Constant *&V);
- bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
- bool ParseMDNodeVector(SmallVectorImpl<Value*> &);
-
-
// Function Semantic Analysis.
class PerFunctionState {
LLParser &P;
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
PerFunctionState &PFS);
+ // Constant Parsing.
+ bool ParseValID(ValID &ID, PerFunctionState *PFS = NULL);
+ bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V);
+ bool ConvertGlobalOrMetadataValIDToValue(const Type *Ty, ValID &ID,
+ Value *&V, PerFunctionState *PFS);
+ bool ParseGlobalValue(const Type *Ty, Constant *&V);
+ bool ParseGlobalTypeAndValue(Constant *&V);
+ bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
+ bool ParseMDNodeVector(SmallVectorImpl<Value*> &, PerFunctionState *PFS);
+
// Function Parsing.
struct ArgInfo {
LocTy Loc;
--- /dev/null
+; RUN: llvm-as < %s | llvm-dis | grep {ret void, !foo !0, !bar !1}
+
+define void @Foo(i32 %a, i32 %b) {
+entry:
+ %0 = add i32 %a, 1 ; <i32> [#uses=1]
+ %two = add i32 %b, 2 ; <i32> [#uses=2]
+
+ call void @llvm.dbg.func.start(metadata !{i32 %0})
+ call void @llvm.dbg.func.start(metadata !{i32 %b, i32 %0})
+ call void @llvm.dbg.func.start(metadata !{i32 %a, metadata !"foo"})
+ call void @llvm.dbg.func.start(metadata !{metadata !0, i32 %two})
+
+ ret void, !foo !0, !bar !1
+}
+
+!0 = metadata !{i32 662302, i32 26, metadata !1, null}
+!1 = metadata !{i32 4, metadata !"foo"}
+
+declare void @llvm.dbg.func.start(metadata) nounwind readnone
+
+!foo = !{ !0 }
+!bar = !{ !1 }