ParseToken(lltok::rbrace, "expected end of struct constant"))
return true;
- ID.ConstantStructElts.reset(new Constant*[Elts.size()]);
+ ID.ConstantStructElts = new Constant*[Elts.size()];
ID.UIntVal = Elts.size();
- memcpy(ID.ConstantStructElts.get(), Elts.data(), Elts.size()*sizeof(Elts[0]));
+ memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
ID.Kind = ValID::t_ConstantStruct;
return false;
}
return true;
if (isPackedStruct) {
- ID.ConstantStructElts.reset(new Constant*[Elts.size()]);
- memcpy(ID.ConstantStructElts.get(), Elts.data(), Elts.size()*sizeof(Elts[0]));
+ ID.ConstantStructElts = new Constant*[Elts.size()];
+ memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
ID.UIntVal = Elts.size();
ID.Kind = ValID::t_PackedConstantStruct;
return false;
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;
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) {
}
}
- 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))
+ if (!GetElementPtrInst::getIndexedType(
+ cast<PointerType>(Elts[0]->getType()->getScalarType())
+ ->getElementType(),
+ Indices))
return Error(ID.Loc, "invalid getelementptr indices");
ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices,
InBounds);
MDBoolField(bool Default = false) : ImplTy(Default) {}
};
struct MDField : public MDFieldImpl<Metadata *> {
- MDField() : ImplTy(nullptr) {}
+ bool AllowNull;
+
+ MDField(bool AllowNull = true) : ImplTy(nullptr), AllowNull(AllowNull) {}
};
struct MDConstant : public MDFieldImpl<ConstantAsMetadata *> {
MDConstant() : ImplTy(nullptr) {}
};
-struct MDStringField : public MDFieldImpl<std::string> {
- MDStringField() : ImplTy(std::string()) {}
+struct MDStringField : public MDFieldImpl<MDString *> {
+ MDStringField() : ImplTy(nullptr) {}
};
struct MDFieldList : public MDFieldImpl<SmallVector<Metadata *, 4>> {
MDFieldList() : ImplTy(SmallVector<Metadata *, 4>()) {}
template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDField &Result) {
if (Lex.getKind() == lltok::kw_null) {
+ if (!Result.AllowNull)
+ return TokError("'" + Name + "' cannot be null");
Lex.Lex();
Result.assign(nullptr);
return false;
if (ParseStringConstant(S))
return true;
- Result.assign(std::move(S));
+ Result.assign(S.empty() ? nullptr : MDString::get(Context, S));
return false;
}
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
OPTIONAL(line, LineField, ); \
OPTIONAL(column, ColumnField, ); \
- REQUIRED(scope, MDField, ); \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(inlinedAt, MDField, );
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;
}
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, ); \
/// ::= !MDLexicalBlock(scope: !0, file: !2, line: 7, column: 9)
bool LLParser::ParseMDLexicalBlock(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(scope, MDField, ); \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(column, ColumnField, );
/// ::= !MDLexicalBlockFile(scope: !0, file: !2, discriminator: 9)
bool LLParser::ParseMDLexicalBlockFile(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(scope, MDField, ); \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(file, MDField, ); \
REQUIRED(discriminator, MDUnsignedField, (0, UINT32_MAX));
PARSE_MD_FIELDS();
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, ); \
bool LLParser::ParseMDLocalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
- OPTIONAL(scope, MDField, ); \
+ REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(name, MDStringField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
/// 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, ); \
return Error(ID.Loc, "element " + Twine(i) +
" of struct initializer doesn't match struct element type");
- V = ConstantStruct::get(
- ST, makeArrayRef(ID.ConstantStructElts.get(), ID.UIntVal));
+ V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts,
+ ID.UIntVal));
} else
return Error(ID.Loc, "constant expression type mismatch");
return false;
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){
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.
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;
}
ParseTypeAndValue(Ptr, Loc, PFS))
return true;
- Type *PtrTy = Ptr->getType();
- if (VectorType *VT = dyn_cast<VectorType>(PtrTy))
- PtrTy = VT->getElementType();
- SequentialType *SeqPtrTy = dyn_cast<SequentialType>(PtrTy);
- if (!SeqPtrTy)
- return Error(Loc, "pointer type is not valid");
- if (Ty != SeqPtrTy->getElementType())
- return Error(ExplicitTypeLoc,
- "explicit pointee type doesn't match operand's pointee type");
-
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)) {
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))
+ if (!GetElementPtrInst::getIndexedType(
+ cast<PointerType>(BaseType->getScalarType())->getElementType(),
+ 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;