#include "LLParser.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/CallingConv.h"
ParseToken(lltok::rbrace, "expected end of struct constant"))
return true;
- ID.ConstantStructElts = new Constant*[Elts.size()];
+ ID.ConstantStructElts = make_unique<Constant *[]>(Elts.size());
ID.UIntVal = Elts.size();
- memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
+ memcpy(ID.ConstantStructElts.get(), Elts.data(),
+ Elts.size() * sizeof(Elts[0]));
ID.Kind = ValID::t_ConstantStruct;
return false;
}
return true;
if (isPackedStruct) {
- ID.ConstantStructElts = new Constant*[Elts.size()];
- memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
+ ID.ConstantStructElts = make_unique<Constant *[]>(Elts.size());
+ memcpy(ID.ConstantStructElts.get(), Elts.data(),
+ Elts.size() * sizeof(Elts[0]));
ID.UIntVal = Elts.size();
ID.Kind = ValID::t_PackedConstantStruct;
return false;
}
/// ParseDILocalVariable:
-/// ::= !DILocalVariable(tag: DW_TAG_arg_variable, scope: !0, name: "foo",
+/// ::= !DILocalVariable(arg: 7, scope: !0, name: "foo",
+/// file: !1, line: 7, type: !2, arg: 2, flags: 7)
+/// ::= !DILocalVariable(scope: !0, name: "foo",
/// file: !1, line: 7, type: !2, arg: 2, flags: 7)
bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
- REQUIRED(tag, DwarfTagField, ); \
REQUIRED(scope, MDField, (/* AllowNull */ false)); \
OPTIONAL(name, MDStringField, ); \
+ OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(type, MDField, ); \
- OPTIONAL(arg, MDUnsignedField, (0, UINT16_MAX)); \
OPTIONAL(flags, DIFlagField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(DILocalVariable,
- (Context, tag.Val, scope.Val, name.Val, file.Val,
- line.Val, type.Val, arg.Val, flags.Val));
+ (Context, scope.Val, name.Val, file.Val, line.Val,
+ type.Val, arg.Val, flags.Val));
return false;
}
V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
return V == nullptr;
case ValID::t_InlineAsm: {
- PointerType *PTy = dyn_cast<PointerType>(Ty);
- FunctionType *FTy =
- PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : nullptr;
- if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
+ assert(ID.FTy);
+ if (!InlineAsm::Verify(ID.FTy, ID.StrVal2))
return Error(ID.Loc, "invalid type for inline asm constraint string");
- V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1,
- (ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2)));
+ V = InlineAsm::get(ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1,
+ (ID.UIntVal >> 1) & 1,
+ (InlineAsm::AsmDialect(ID.UIntVal >> 2)));
return false;
}
case ValID::t_GlobalName:
return Error(ID.Loc, "element " + Twine(i) +
" of struct initializer doesn't match struct element type");
- V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts,
- ID.UIntVal));
+ V = ConstantStruct::get(
+ ST, makeArrayRef(ID.ConstantStructElts.get(), ID.UIntVal));
} else
return Error(ID.Loc, "constant expression type mismatch");
return false;
case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS);
case lltok::kw_invoke: return ParseInvoke(Inst, PFS);
case lltok::kw_resume: return ParseResume(Inst, PFS);
+ case lltok::kw_cleanupret: return ParseCleanupRet(Inst, PFS);
+ case lltok::kw_catchret: return ParseCatchRet(Inst, PFS);
+ case lltok::kw_catchpad: return ParseCatchPad(Inst, PFS);
+ case lltok::kw_terminatepad: return ParseTerminatePad(Inst, PFS);
+ case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS);
+ case lltok::kw_catchendpad: return ParseCatchEndPad(Inst, PFS);
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
Ty = FunctionType::get(RetType, ParamTypes, false);
}
+ CalleeID.FTy = Ty;
+
// Look up the callee.
Value *Callee;
if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))
return false;
}
+bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
+ PerFunctionState &PFS) {
+ if (ParseToken(lltok::lsquare, "expected '[' in cleanuppad"))
+ return true;
+
+ while (Lex.getKind() != lltok::rsquare) {
+ // If this isn't the first argument, we need a comma.
+ if (!Args.empty() &&
+ ParseToken(lltok::comma, "expected ',' in argument list"))
+ return true;
+
+ // Parse the argument.
+ LocTy ArgLoc;
+ Type *ArgTy = nullptr;
+ if (ParseType(ArgTy, ArgLoc))
+ return true;
+
+ Value *V;
+ if (ArgTy->isMetadataTy()) {
+ if (ParseMetadataAsValue(V, PFS))
+ return true;
+ } else {
+ if (ParseValue(ArgTy, V, PFS))
+ return true;
+ }
+ Args.push_back(V);
+ }
+
+ Lex.Lex(); // Lex the ']'.
+ return false;
+}
+
+/// ParseCleanupRet
+/// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue)
+bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
+ Type *RetTy = nullptr;
+ Value *RetVal = nullptr;
+ if (ParseType(RetTy, /*AllowVoid=*/true))
+ return true;
+
+ if (!RetTy->isVoidTy())
+ if (ParseValue(RetTy, RetVal, PFS))
+ return true;
+
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
+ return true;
+
+ BasicBlock *UnwindBB = nullptr;
+ if (Lex.getKind() == lltok::kw_to) {
+ Lex.Lex();
+ if (ParseToken(lltok::kw_caller, "expected 'caller' in cleanupret"))
+ return true;
+ } else {
+ if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
+ return true;
+ }
+ }
+
+ Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB);
+ return false;
+}
+
+/// ParseCatchRet
+/// ::= 'catchret' TypeAndValue
+bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
+ BasicBlock *BB;
+ if (ParseTypeAndBasicBlock(BB, PFS))
+ return true;
+
+ Inst = CatchReturnInst::Create(BB);
+ return false;
+}
+
+/// ParseCatchPad
+/// ::= 'catchpad' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue
+bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
+ Type *RetType = nullptr;
+
+ SmallVector<Value *, 8> Args;
+ if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
+ return true;
+
+ BasicBlock *NormalBB, *UnwindBB;
+ if (ParseToken(lltok::kw_to, "expected 'to' in catchpad") ||
+ ParseTypeAndBasicBlock(NormalBB, PFS) ||
+ ParseToken(lltok::kw_unwind, "expected 'unwind' in catchpad") ||
+ ParseTypeAndBasicBlock(UnwindBB, PFS))
+ return true;
+
+ Inst = CatchPadInst::Create(RetType, NormalBB, UnwindBB, Args);
+ return false;
+}
+
+/// ParseTerminatePad
+/// ::= 'terminatepad' ParamList 'to' TypeAndValue
+bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) {
+ SmallVector<Value *, 8> Args;
+ if (ParseExceptionArgs(Args, PFS))
+ return true;
+
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in terminatepad"))
+ return true;
+
+ BasicBlock *UnwindBB = nullptr;
+ if (Lex.getKind() == lltok::kw_to) {
+ Lex.Lex();
+ if (ParseToken(lltok::kw_caller, "expected 'caller' in terminatepad"))
+ return true;
+ } else {
+ if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
+ return true;
+ }
+ }
+
+ Inst = TerminatePadInst::Create(Context, UnwindBB, Args);
+ return false;
+}
+
+/// ParseCleanupPad
+/// ::= 'cleanuppad' ParamList
+bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
+ Type *RetType = nullptr;
+
+ SmallVector<Value *, 8> Args;
+ if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
+ return true;
+
+ Inst = CleanupPadInst::Create(RetType, Args);
+ return false;
+}
+
+/// ParseCatchEndPad
+/// ::= 'catchendpad' unwind ('to' 'caller' | TypeAndValue)
+bool LLParser::ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS) {
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad"))
+ return true;
+
+ BasicBlock *UnwindBB = nullptr;
+ if (Lex.getKind() == lltok::kw_to) {
+ Lex.Lex();
+ if (Lex.getKind() == lltok::kw_caller) {
+ Lex.Lex();
+ } else {
+ return true;
+ }
+ } else {
+ if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
+ return true;
+ }
+ }
+
+ Inst = CatchEndPadInst::Create(Context, UnwindBB);
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Binary Operators.
//===----------------------------------------------------------------------===//
Ty = FunctionType::get(RetType, ParamTypes, false);
}
+ CalleeID.FTy = Ty;
+
// Look up the callee.
Value *Callee;
if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))