/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
/// module.
bool LLParser::ValidateEndOfModule() {
- // Handle any instruction metadata forward references.
- if (!ForwardRefInstMetadata.empty()) {
- for (DenseMap<Instruction*, std::vector<MDRef> >::iterator
- I = ForwardRefInstMetadata.begin(), E = ForwardRefInstMetadata.end();
- I != E; ++I) {
- Instruction *Inst = I->first;
- const std::vector<MDRef> &MDList = I->second;
-
- for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
- unsigned SlotNo = MDList[i].MDSlot;
-
- if (SlotNo >= NumberedMetadata.size() ||
- NumberedMetadata[SlotNo] == nullptr)
- return Error(MDList[i].Loc, "use of undefined metadata '!" +
- Twine(SlotNo) + "'");
- assert(!NumberedMetadata[SlotNo]->isFunctionLocal() &&
- "Unexpected function-local metadata");
- Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]);
- }
- }
- ForwardRefInstMetadata.clear();
- }
-
for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++)
UpgradeInstWithTBAATag(InstsWithTBAATag[I]);
"use of undefined metadata '!" +
Twine(ForwardRefMDNodes.begin()->first) + "'");
+ // Resolve metadata cycles.
+ for (auto &N : NumberedMetadata)
+ if (auto *U = cast_or_null<UniquableMDNode>(N))
+ U->resolveCycles();
// Look for intrinsic functions and CallInst that need to be upgraded
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
// MDNode:
// ::= '!' MDNodeNumber
-//
-/// This version of ParseMDNodeID returns the slot number and null in the case
-/// of a forward reference.
-bool LLParser::ParseMDNodeID(MDNode *&Result, unsigned &SlotNo) {
- // !{ ..., !42, ... }
- if (ParseUInt32(SlotNo)) return true;
-
- // Check existing MDNode.
- if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != nullptr)
- Result = NumberedMetadata[SlotNo];
- else
- Result = nullptr;
- return false;
-}
-
bool LLParser::ParseMDNodeID(MDNode *&Result) {
// !{ ..., !42, ... }
unsigned MID = 0;
- if (ParseMDNodeID(Result, MID)) return true;
+ if (ParseUInt32(MID))
+ return true;
// If not a forward reference, just return it now.
- if (Result) return false;
+ if (MID < NumberedMetadata.size() && NumberedMetadata[MID] != nullptr) {
+ Result = NumberedMetadata[MID];
+ return false;
+ }
// Otherwise, create MDNode forward reference.
- MDNode *FwdNode = MDNode::getTemporary(Context, None);
+ MDTuple *FwdNode = MDTuple::getTemporary(Context, None);
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
if (NumberedMetadata.size() <= MID)
NumberedMetadata.resize(MID+1);
- NumberedMetadata[MID] = FwdNode;
+ NumberedMetadata[MID].reset(FwdNode);
Result = FwdNode;
return false;
}
Lex.Lex();
unsigned MetadataID = 0;
- LocTy TyLoc;
- Type *Ty = nullptr;
- SmallVector<Value *, 16> Elts;
+ MDNode *Init;
if (ParseUInt32(MetadataID) ||
- ParseToken(lltok::equal, "expected '=' here") ||
- ParseType(Ty, TyLoc) ||
- ParseToken(lltok::exclaim, "Expected '!' here") ||
- ParseToken(lltok::lbrace, "Expected '{' here") ||
- ParseMDNodeVector(Elts, nullptr) ||
- ParseToken(lltok::rbrace, "expected end of metadata node"))
+ ParseToken(lltok::equal, "expected '=' here"))
return true;
- MDNode *Init = MDNode::get(Context, Elts);
+ // Detect common error, from old metadata syntax.
+ if (Lex.getKind() == lltok::Type)
+ return TokError("unexpected type in metadata definition");
+
+ bool IsDistinct = EatIfPresent(lltok::kw_distinct);
+ if (Lex.getKind() == lltok::MetadataVar) {
+ if (ParseSpecializedMDNode(Init, IsDistinct))
+ return true;
+ } else if (ParseToken(lltok::exclaim, "Expected '!' here") ||
+ ParseMDTuple(Init, IsDistinct))
+ return true;
// See if this was forward referenced, if so, handle it.
- std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator
- FI = ForwardRefMDNodes.find(MetadataID);
+ auto FI = ForwardRefMDNodes.find(MetadataID);
if (FI != ForwardRefMDNodes.end()) {
- MDNode *Temp = FI->second.first;
+ MDTuple *Temp = FI->second.first;
Temp->replaceAllUsesWith(Init);
MDNode::deleteTemporary(Temp);
ForwardRefMDNodes.erase(FI);
if (NumberedMetadata[MetadataID] != nullptr)
return TokError("Metadata id is already used");
- NumberedMetadata[MetadataID] = Init;
+ NumberedMetadata[MetadataID].reset(Init);
}
return false;
if (Ty->isFunctionTy() || Ty->isLabelTy())
return Error(TyLoc, "invalid type for global variable");
- GlobalVariable *GV = nullptr;
+ GlobalValue *GVal = nullptr;
// See if the global was forward referenced, if so, use the global.
if (!Name.empty()) {
- if (GlobalValue *GVal = M->getNamedValue(Name)) {
+ GVal = M->getNamedValue(Name);
+ if (GVal) {
if (!ForwardRefVals.erase(Name) || !isa<GlobalValue>(GVal))
return Error(NameLoc, "redefinition of global '@" + Name + "'");
- GV = cast<GlobalVariable>(GVal);
}
} else {
std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
I = ForwardRefValIDs.find(NumberedVals.size());
if (I != ForwardRefValIDs.end()) {
- GV = cast<GlobalVariable>(I->second.first);
+ GVal = I->second.first;
ForwardRefValIDs.erase(I);
}
}
- if (!GV) {
+ GlobalVariable *GV;
+ if (!GVal) {
GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr,
Name, nullptr, GlobalVariable::NotThreadLocal,
AddrSpace);
} else {
- if (GV->getType()->getElementType() != Ty)
+ if (GVal->getType()->getElementType() != Ty)
return Error(TyLoc,
"forward reference and definition of global have different types");
+ GV = cast<GlobalVariable>(GVal);
+
// Move the forward-reference to the correct spot in the module.
M->getGlobalList().splice(M->global_end(), M->getGlobalList(), GV);
}
GV->setAlignment(Alignment);
} else {
Comdat *C;
- if (parseOptionalComdat(C))
+ if (parseOptionalComdat(Name, C))
return true;
if (C)
GV->setComdat(C);
LocTy AttrGrpLoc = Lex.getLoc();
Lex.Lex();
- assert(Lex.getKind() == lltok::AttrGrpID);
+ if (Lex.getKind() != lltok::AttrGrpID)
+ return TokError("expected attribute group id");
+
unsigned VarID = Lex.getUIntVal();
std::vector<unsigned> unused;
LocTy BuiltinLoc;
unsigned MDK = M->getMDKindID(Name);
Lex.Lex();
- MDNode *Node;
- SMLoc Loc = Lex.getLoc();
-
- if (ParseToken(lltok::exclaim, "expected '!' here"))
+ MDNode *N;
+ if (ParseMDNode(N))
return true;
- // This code is similar to that of ParseMetadataValue, however it needs to
- // have special-case code for a forward reference; see the comments on
- // ForwardRefInstMetadata for details. Also, MDStrings are not supported
- // at the top level here.
- if (Lex.getKind() == lltok::lbrace) {
- ValID ID;
- if (ParseMetadataListValue(ID, PFS))
- return true;
- assert(ID.Kind == ValID::t_MDNode);
- if (ID.MDNodeVal->isFunctionLocal())
- return Error(Loc, "unexpected function-local metadata");
- Inst->setMetadata(MDK, ID.MDNodeVal);
- } else {
- unsigned NodeID = 0;
- if (ParseMDNodeID(Node, NodeID))
- return true;
- if (Node) {
- // If we got the node, add it to the instruction.
- Inst->setMetadata(MDK, Node);
- } else {
- MDRef R = { Loc, MDK, NodeID };
- // Otherwise, remember that this should be resolved later.
- ForwardRefInstMetadata[Inst].push_back(R);
- }
- }
-
+ Inst->setMetadata(MDK, N);
if (MDK == LLVMContext::MD_tbaa)
InstsWithTBAATag.push_back(Inst);
//===----------------------------------------------------------------------===//
/// ParseType - Parse a type.
-bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
+bool LLParser::ParseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
SMLoc TypeLoc = Lex.getLoc();
switch (Lex.getKind()) {
default:
- return TokError("expected type");
+ return TokError(Msg);
case lltok::Type:
// Type ::= 'float' | 'void' (etc)
Result = Lex.getTyVal();
if (ParseType(ArgTy, ArgLoc))
return true;
- // Otherwise, handle normal operands.
- if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
- return true;
+ if (ArgTy->isMetadataTy()) {
+ if (ParseMetadataAsValue(V, PFS))
+ return true;
+ } else {
+ // Otherwise, handle normal operands.
+ if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
+ return true;
+ }
ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(),
AttrIndex++,
ArgAttrs)));
ID.StrVal = Lex.getStrVal();
ID.Kind = ValID::t_LocalName;
break;
- case lltok::exclaim: // !42, !{...}, or !"foo"
- return ParseMetadataValue(ID, PFS);
case lltok::APSInt:
ID.APSIntVal = Lex.getAPSIntVal();
ID.Kind = ValID::t_APSInt;
ParseGlobalValue(Ty, V);
}
-bool LLParser::parseOptionalComdat(Comdat *&C) {
+bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) {
C = nullptr;
+
+ LocTy KwLoc = Lex.getLoc();
if (!EatIfPresent(lltok::kw_comdat))
return false;
- if (Lex.getKind() != lltok::ComdatVar)
- return TokError("expected comdat variable");
- LocTy Loc = Lex.getLoc();
- StringRef Name = Lex.getStrVal();
- C = getComdat(Name, Loc);
- Lex.Lex();
+
+ if (EatIfPresent(lltok::lparen)) {
+ if (Lex.getKind() != lltok::ComdatVar)
+ return TokError("expected comdat variable");
+ C = getComdat(Lex.getStrVal(), Lex.getLoc());
+ Lex.Lex();
+ if (ParseToken(lltok::rparen, "expected ')' after comdat var"))
+ return true;
+ } else {
+ if (GlobalName.empty())
+ return TokError("comdat cannot be unnamed");
+ C = getComdat(GlobalName, KwLoc);
+ }
+
return false;
}
return false;
}
-bool LLParser::ParseMetadataListValue(ValID &ID, PerFunctionState *PFS) {
- assert(Lex.getKind() == lltok::lbrace);
- Lex.Lex();
-
- SmallVector<Value*, 16> Elts;
- if (ParseMDNodeVector(Elts, PFS) ||
- ParseToken(lltok::rbrace, "expected end of metadata node"))
+bool LLParser::ParseMDTuple(MDNode *&MD, bool IsDistinct) {
+ SmallVector<Metadata *, 16> Elts;
+ if (ParseMDNodeVector(Elts))
return true;
- ID.MDNodeVal = MDNode::get(Context, Elts);
- ID.Kind = ValID::t_MDNode;
+ MD = (IsDistinct ? MDTuple::getDistinct : MDTuple::get)(Context, Elts);
return false;
}
-/// ParseMetadataValue
-/// ::= !42
-/// ::= !{...}
-/// ::= !"string"
-bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) {
- assert(Lex.getKind() == lltok::exclaim);
- Lex.Lex();
+/// MDNode:
+/// ::= !{ ... }
+/// ::= !7
+/// ::= !MDLocation(...)
+bool LLParser::ParseMDNode(MDNode *&N) {
+ if (Lex.getKind() == lltok::MetadataVar)
+ return ParseSpecializedMDNode(N);
- // MDNode:
+ return ParseToken(lltok::exclaim, "expected '!' here") ||
+ ParseMDNodeTail(N);
+}
+
+bool LLParser::ParseMDNodeTail(MDNode *&N) {
// !{ ... }
if (Lex.getKind() == lltok::lbrace)
- return ParseMetadataListValue(ID, PFS);
+ return ParseMDTuple(N);
- // Standalone metadata reference
// !42
- if (Lex.getKind() == lltok::APSInt) {
- if (ParseMDNodeID(ID.MDNodeVal)) return true;
- ID.Kind = ValID::t_MDNode;
+ 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 >> 16);
+ 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
+/// ::= metadata i32 %local
+/// ::= metadata i32 @global
+/// ::= metadata i32 7
+/// ::= metadata !0
+/// ::= metadata !{...}
+/// ::= metadata !"string"
+bool LLParser::ParseMetadataAsValue(Value *&V, PerFunctionState &PFS) {
+ // Note: the type 'metadata' has already been parsed.
+ Metadata *MD;
+ if (ParseMetadata(MD, &PFS))
+ return true;
+
+ V = MetadataAsValue::get(Context, MD);
+ return false;
+}
+
+/// ParseValueAsMetadata
+/// ::= i32 %local
+/// ::= i32 @global
+/// ::= i32 7
+bool LLParser::ParseValueAsMetadata(Metadata *&MD, PerFunctionState *PFS) {
+ Type *Ty;
+ LocTy Loc;
+ if (ParseType(Ty, "expected metadata operand", Loc))
+ return true;
+ if (Ty->isMetadataTy())
+ return Error(Loc, "invalid metadata-value-metadata roundtrip");
+
+ Value *V;
+ if (ParseValue(Ty, V, PFS))
+ return true;
+
+ MD = ValueAsMetadata::get(V);
+ return false;
+}
+
+/// ParseMetadata
+/// ::= i32 %local
+/// ::= i32 @global
+/// ::= i32 7
+/// ::= !42
+/// ::= !{...}
+/// ::= !"string"
+/// ::= !MDLocation(...)
+bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) {
+ if (Lex.getKind() == lltok::MetadataVar) {
+ MDNode *N;
+ if (ParseSpecializedMDNode(N))
+ return true;
+ MD = N;
return false;
}
+ // ValueAsMetadata:
+ // <type> <value>
+ if (Lex.getKind() != lltok::exclaim)
+ return ParseValueAsMetadata(MD, PFS);
+
+ // '!'.
+ assert(Lex.getKind() == lltok::exclaim && "Expected '!' here");
+ Lex.Lex();
+
// MDString:
// ::= '!' STRINGCONSTANT
- if (ParseMDString(ID.MDStringVal)) return true;
- ID.Kind = ValID::t_MDString;
+ if (Lex.getKind() == lltok::StringConstant) {
+ MDString *S;
+ if (ParseMDString(S))
+ return true;
+ MD = S;
+ return false;
+ }
+
+ // MDNode:
+ // !{ ... }
+ // !7
+ MDNode *N;
+ if (ParseMDNodeTail(N))
+ return true;
+ MD = N;
return false;
}
(ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2)));
return false;
}
- case ValID::t_MDNode:
- if (!Ty->isMetadataTy())
- return Error(ID.Loc, "metadata value must have metadata type");
- V = ID.MDNodeVal;
- return false;
- case ValID::t_MDString:
- if (!Ty->isMetadataTy())
- return Error(ID.Loc, "metadata value must have metadata type");
- V = ID.MDStringVal;
- return false;
case ValID::t_GlobalName:
V = GetGlobalVal(ID.StrVal, Ty, ID.Loc);
return V == nullptr;
BuiltinLoc) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
- parseOptionalComdat(C) ||
+ parseOptionalComdat(FunctionName, C) ||
ParseOptionalAlignment(Alignment) ||
(EatIfPresent(lltok::kw_gc) &&
ParseStringConstant(GC)) ||
//===----------------------------------------------------------------------===//
/// ParseMDNodeVector
-/// ::= Element (',' Element)*
+/// ::= { Element (',' Element)* }
/// Element
/// ::= 'null' | TypeAndValue
-bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
- PerFunctionState *PFS) {
+bool LLParser::ParseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
+ if (ParseToken(lltok::lbrace, "expected '{' here"))
+ return true;
+
// Check for an empty list.
- if (Lex.getKind() == lltok::rbrace)
+ if (EatIfPresent(lltok::rbrace))
return false;
- bool IsLocal = false;
do {
- if (IsLocal)
- return TokError("unexpected operand after function-local metadata");
-
// Null is a special case since it is typeless.
if (EatIfPresent(lltok::kw_null)) {
Elts.push_back(nullptr);
continue;
}
- Value *V = nullptr;
- if (ParseTypeAndValue(V, PFS)) return true;
- Elts.push_back(V);
-
- if (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal())
- return TokError("unexpected nested function-local metadata");
- if (!V->getType()->isMetadataTy() && !isa<Constant>(V)) {
- assert(PFS && "Unexpected function-local metadata without PFS");
- if (Elts.size() > 1)
- return TokError("unexpected function-local metadata");
- IsLocal = true;
- }
+ Metadata *MD;
+ if (ParseMetadata(MD, nullptr))
+ return true;
+ Elts.push_back(MD);
} while (EatIfPresent(lltok::comma));
- return false;
+ return ParseToken(lltok::rbrace, "expected end of metadata node");
}
//===----------------------------------------------------------------------===//