#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InlineAsm.h"
return true;
if (!Val0->getType()->isAggregateType())
return Error(ID.Loc, "insertvalue operand must be aggregate type");
- if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices))
+ Type *IndexedType =
+ ExtractValueInst::getIndexedType(Val0->getType(), Indices);
+ if (!IndexedType)
return Error(ID.Loc, "invalid indices for insertvalue");
+ if (IndexedType != Val1->getType())
+ return Error(ID.Loc, "insertvalue operand and field disagree in type: '" +
+ getTypeString(Val1->getType()) +
+ "' instead of '" + getTypeString(IndexedType) +
+ "'");
ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, Indices);
ID.Kind = ValID::t_Constant;
return false;
if (Opc == Instruction::GetElementPtr) {
if (Elts.size() == 0 ||
!Elts[0]->getType()->getScalarType()->isPointerTy())
- return Error(ID.Loc, "getelementptr requires pointer operand");
+ return Error(ID.Loc, "base of getelementptr must be a pointer");
+
+ Type *BaseType = Elts[0]->getType();
+ auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
+ for (Constant *Val : Indices) {
+ Type *ValTy = Val->getType();
+ if (!ValTy->getScalarType()->isIntegerTy())
+ return Error(ID.Loc, "getelementptr index must be an integer");
+ if (ValTy->isVectorTy() != BaseType->isVectorTy())
+ return Error(ID.Loc, "getelementptr index type missmatch");
+ if (ValTy->isVectorTy()) {
+ unsigned ValNumEl = cast<VectorType>(ValTy)->getNumElements();
+ unsigned PtrNumEl = cast<VectorType>(BaseType)->getNumElements();
+ if (ValNumEl != PtrNumEl)
+ return Error(
+ ID.Loc,
+ "getelementptr vector index has a wrong number of elements");
+ }
+ }
+
+ if (!Indices.empty() && !BasePointerType->getElementType()->isSized())
+ return Error(ID.Loc, "base element of getelementptr must be sized");
+
if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), Indices))
- return Error(ID.Loc, "invalid indices for getelementptr");
+ return Error(ID.Loc, "invalid getelementptr indices");
ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices,
InBounds);
} else if (Opc == Instruction::Select) {
DwarfLangField() : MDUnsignedField(0, dwarf::DW_LANG_hi_user) {}
};
+struct DIFlagField : public MDUnsignedField {
+ DIFlagField() : MDUnsignedField(0, UINT32_MAX) {}
+};
+
struct MDSignedField : public MDFieldImpl<int64_t> {
int64_t Min;
int64_t Max;
return false;
}
+/// DIFlagField
+/// ::= uint32
+/// ::= DIFlagVector
+/// ::= DIFlagVector '|' DIFlagFwdDecl '|' uint32 '|' DIFlagPublic
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) {
+ assert(Result.Max == UINT32_MAX && "Expected only 32-bits");
+
+ // Parser for a single flag.
+ auto parseFlag = [&](unsigned &Val) {
+ if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned())
+ return ParseUInt32(Val);
+
+ if (Lex.getKind() != lltok::DIFlag)
+ return TokError("expected debug info flag");
+
+ Val = DIDescriptor::getFlag(Lex.getStrVal());
+ if (!Val)
+ return TokError(Twine("invalid debug info flag flag '") +
+ Lex.getStrVal() + "'");
+ Lex.Lex();
+ return false;
+ };
+
+ // Parse the flags and combine them together.
+ unsigned Combined = 0;
+ do {
+ unsigned Val;
+ if (parseFlag(Val))
+ return true;
+ Combined |= Val;
+ } while (EatIfPresent(lltok::bar));
+
+ Result.assign(Combined);
+ return false;
+}
+
template <>
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
MDSignedField &Result) {
OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(extraData, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(align, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(elements, MDField, ); \
OPTIONAL(runtimeLang, DwarfLangField, ); \
OPTIONAL(vtableHolder, MDField, ); \
bool LLParser::ParseMDSubroutineType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
REQUIRED(types, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
OPTIONAL(containingType, MDField, ); \
OPTIONAL(virtuality, DwarfVirtualityField, ); \
OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(isOptimized, MDBoolField, ); \
OPTIONAL(function, MDConstant, ); \
OPTIONAL(templateParams, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(type, MDField, ); \
OPTIONAL(arg, MDUnsignedField, (0, UINT8_MAX)); \
- OPTIONAL(flags, MDUnsignedField, (0, UINT32_MAX)); \
+ OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(inlinedAt, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs.hasAttributes())
+ if (FnAttrs.hasAttributes()) {
+ if (FnAttrs.hasAlignmentAttr())
+ return Error(CallLoc, "invoke instructions may not have an alignment");
+
Attrs.push_back(AttributeSet::get(RetType->getContext(),
AttributeSet::FunctionIndex,
FnAttrs));
+ }
// Finish off the Attribute and check them
AttributeSet PAL = AttributeSet::get(Context, Attrs);
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs.hasAttributes())
+ if (FnAttrs.hasAttributes()) {
+ if (FnAttrs.hasAlignmentAttr())
+ return Error(CallLoc, "call instructions may not have an alignment");
+
Attrs.push_back(AttributeSet::get(RetType->getContext(),
AttributeSet::FunctionIndex,
FnAttrs));
+ }
// Finish off the Attribute and check them
AttributeSet PAL = AttributeSet::get(Context, Attrs);