aboutsummaryrefslogtreecommitdiffstats
path: root/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r--lib/AsmParser/LLParser.cpp101
1 files changed, 74 insertions, 27 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 9e7354e..103c8c4 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -2270,13 +2270,13 @@ bool LLParser::PerFunctionState::SetInstName(int NameID,
/// forward reference record if needed.
BasicBlock *LLParser::PerFunctionState::GetBB(const std::string &Name,
LocTy Loc) {
- return cast_or_null<BasicBlock>(GetVal(Name,
- Type::getLabelTy(F.getContext()), Loc));
+ return dyn_cast_or_null<BasicBlock>(GetVal(Name,
+ Type::getLabelTy(F.getContext()), Loc));
}
BasicBlock *LLParser::PerFunctionState::GetBB(unsigned ID, LocTy Loc) {
- return cast_or_null<BasicBlock>(GetVal(ID,
- Type::getLabelTy(F.getContext()), Loc));
+ return dyn_cast_or_null<BasicBlock>(GetVal(ID,
+ Type::getLabelTy(F.getContext()), Loc));
}
/// DefineBB - Define the specified basic block, which is either named or
@@ -2512,7 +2512,12 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
if (!F) {
// Make a global variable as a placeholder for this reference.
- GlobalValue *&FwdRef = ForwardRefBlockAddresses[Fn][Label];
+ GlobalValue *&FwdRef =
+ ForwardRefBlockAddresses.insert(std::make_pair(
+ std::move(Fn),
+ std::map<ValID, GlobalValue *>()))
+ .first->second.insert(std::make_pair(std::move(Label), nullptr))
+ .first->second;
if (!FwdRef)
FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false,
GlobalValue::InternalLinkage, nullptr, "");
@@ -2772,11 +2777,23 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
unsigned Opc = Lex.getUIntVal();
SmallVector<Constant*, 16> Elts;
bool InBounds = false;
+ Type *Ty;
Lex.Lex();
+
if (Opc == Instruction::GetElementPtr)
InBounds = EatIfPresent(lltok::kw_inbounds);
- if (ParseToken(lltok::lparen, "expected '(' in constantexpr") ||
- ParseGlobalValueVector(Elts) ||
+
+ if (ParseToken(lltok::lparen, "expected '(' in constantexpr"))
+ return true;
+
+ LocTy ExplicitTypeLoc = Lex.getLoc();
+ if (Opc == Instruction::GetElementPtr) {
+ if (ParseType(Ty) ||
+ ParseToken(lltok::comma, "expected comma after getelementptr's type"))
+ return true;
+ }
+
+ if (ParseGlobalValueVector(Elts) ||
ParseToken(lltok::rparen, "expected ')' in constantexpr"))
return true;
@@ -2787,6 +2804,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
Type *BaseType = Elts[0]->getType();
auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
+ if (Ty != BasePointerType->getElementType())
+ return Error(
+ ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
for (Constant *Val : Indices) {
@@ -2805,7 +2826,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
}
}
- if (!Indices.empty() && !BasePointerType->getElementType()->isSized())
+ SmallPtrSet<const Type*, 4> Visited;
+ if (!Indices.empty() &&
+ !BasePointerType->getElementType()->isSized(&Visited))
return Error(ID.Loc, "base element of getelementptr must be sized");
if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), Indices))
@@ -2976,6 +2999,8 @@ struct ColumnField : public MDUnsignedField {
};
struct DwarfTagField : public MDUnsignedField {
DwarfTagField() : MDUnsignedField(0, dwarf::DW_TAG_hi_user) {}
+ DwarfTagField(dwarf::Tag DefaultTag)
+ : MDUnsignedField(DefaultTag, dwarf::DW_TAG_hi_user) {}
};
struct DwarfAttEncodingField : public MDUnsignedField {
DwarfAttEncodingField() : MDUnsignedField(0, dwarf::DW_ATE_hi_user) {}
@@ -3323,8 +3348,8 @@ bool LLParser::ParseMDLocation(MDNode *&Result, bool IsDistinct) {
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
- auto get = (IsDistinct ? MDLocation::getDistinct : MDLocation::get);
- Result = get(Context, line.Val, column.Val, scope.Val, inlinedAt.Val);
+ Result = GET_OR_DISTINCT(
+ MDLocation, (Context, line.Val, column.Val, scope.Val, inlinedAt.Val));
return false;
}
@@ -3373,7 +3398,7 @@ bool LLParser::ParseMDEnumerator(MDNode *&Result, bool IsDistinct) {
/// ::= !MDBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32)
bool LLParser::ParseMDBasicType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(tag, DwarfTagField, ); \
+ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \
OPTIONAL(name, MDStringField, ); \
OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
@@ -3509,7 +3534,7 @@ bool LLParser::ParseMDCompileUnit(MDNode *&Result, bool IsDistinct) {
bool LLParser::ParseMDSubprogram(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(scope, MDField, ); \
- REQUIRED(name, MDStringField, ); \
+ OPTIONAL(name, MDStringField, ); \
OPTIONAL(linkageName, MDStringField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
@@ -3604,9 +3629,9 @@ bool LLParser::ParseMDTemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
/// name: "V", type: !1, value: i32 7)
bool LLParser::ParseMDTemplateValueParameter(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(tag, DwarfTagField, ); \
+ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \
OPTIONAL(name, MDStringField, ); \
- REQUIRED(type, MDField, ); \
+ OPTIONAL(type, MDField, ); \
REQUIRED(value, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
@@ -3624,7 +3649,7 @@ bool LLParser::ParseMDTemplateValueParameter(MDNode *&Result, bool IsDistinct) {
bool LLParser::ParseMDGlobalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(scope, MDField, ); \
- REQUIRED(name, MDStringField, ); \
+ OPTIONAL(name, MDStringField, ); \
OPTIONAL(linkageName, MDStringField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
@@ -3710,7 +3735,7 @@ bool LLParser::ParseMDExpression(MDNode *&Result, bool IsDistinct) {
/// getter: "getFoo", attributes: 7, type: !2)
bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(name, MDStringField, ); \
+ OPTIONAL(name, MDStringField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(setter, MDStringField, ); \
@@ -4297,7 +4322,9 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
}
BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
- if (!BB) return true;
+ if (!BB)
+ return Error(NameLoc,
+ "unable to create block named '" + Name + "'");
std::string NameStr;
@@ -5032,7 +5059,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
ParseTypeAndValue(PersFn, PersFnLoc, PFS))
return true;
- LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0);
+ std::unique_ptr<LandingPadInst> LP(LandingPadInst::Create(Ty, PersFn, 0));
LP->setCleanup(EatIfPresent(lltok::kw_cleanup));
while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){
@@ -5046,10 +5073,8 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
Value *V;
LocTy VLoc;
- if (ParseTypeAndValue(V, VLoc, PFS)) {
- delete LP;
+ if (ParseTypeAndValue(V, VLoc, PFS))
return true;
- }
// A 'catch' type expects a non-array constant. A filter clause expects an
// array constant.
@@ -5061,10 +5086,13 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
Error(VLoc, "'filter' clause has an invalid type");
}
- LP->addClause(cast<Constant>(V));
+ Constant *CV = dyn_cast<Constant>(V);
+ if (!CV)
+ return Error(VLoc, "clause argument must be a constant");
+ LP->addClause(CV);
}
- Inst = LP;
+ Inst = LP.release();
return false;
}
@@ -5241,7 +5269,11 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Lex.Lex();
}
- if (ParseTypeAndValue(Val, Loc, PFS) ||
+ Type *Ty = nullptr;
+ LocTy ExplicitTypeLoc = Lex.getLoc();
+ if (ParseType(Ty) ||
+ ParseToken(lltok::comma, "expected comma after load's type") ||
+ ParseTypeAndValue(Val, Loc, PFS) ||
ParseScopeAndOrdering(isAtomic, Scope, Ordering) ||
ParseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
@@ -5254,6 +5286,10 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
if (Ordering == Release || Ordering == AcquireRelease)
return Error(Loc, "atomic load cannot use Release ordering");
+ if (Ty != cast<PointerType>(Val->getType())->getElementType())
+ return Error(ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
+
Inst = new LoadInst(Val, "", isVolatile, Alignment, Ordering, Scope);
return AteExtraComma ? InstExtraComma : InstNormal;
}
@@ -5440,13 +5476,22 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
bool InBounds = EatIfPresent(lltok::kw_inbounds);
- if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
+ Type *Ty = nullptr;
+ LocTy ExplicitTypeLoc = Lex.getLoc();
+ if (ParseType(Ty) ||
+ ParseToken(lltok::comma, "expected comma after getelementptr's type") ||
+ ParseTypeAndValue(Ptr, Loc, PFS))
+ return true;
Type *BaseType = Ptr->getType();
PointerType *BasePointerType = dyn_cast<PointerType>(BaseType->getScalarType());
if (!BasePointerType)
return Error(Loc, "base of getelementptr must be a pointer");
+ if (Ty != BasePointerType->getElementType())
+ return Error(ExplicitTypeLoc,
+ "explicit pointee type doesn't match operand's pointee type");
+
SmallVector<Value*, 16> Indices;
bool AteExtraComma = false;
while (EatIfPresent(lltok::comma)) {
@@ -5469,12 +5514,14 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
Indices.push_back(Val);
}
- if (!Indices.empty() && !BasePointerType->getElementType()->isSized())
+ SmallPtrSet<const Type*, 4> Visited;
+ if (!Indices.empty() &&
+ !BasePointerType->getElementType()->isSized(&Visited))
return Error(Loc, "base element of getelementptr must be sized");
if (!GetElementPtrInst::getIndexedType(BaseType, Indices))
return Error(Loc, "invalid getelementptr indices");
- Inst = GetElementPtrInst::Create(Ptr, Indices);
+ Inst = GetElementPtrInst::Create(Ty, Ptr, Indices);
if (InBounds)
cast<GetElementPtrInst>(Inst)->setIsInBounds(true);
return AteExtraComma ? InstExtraComma : InstNormal;