diff options
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
| -rw-r--r-- | lib/AsmParser/LLParser.cpp | 206 | 
1 files changed, 109 insertions, 97 deletions
| diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 4cd986e143b6..58ea9296afda 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -130,10 +130,9 @@ bool LLParser::ValidateEndOfModule() {        B.merge(NumberedAttrBuilders[Attr]);      if (Function *Fn = dyn_cast<Function>(V)) { -      AttributeSet AS = Fn->getAttributes(); -      AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); -      AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, -                               AS.getFnAttributes()); +      AttributeList AS = Fn->getAttributes(); +      AttrBuilder FnAttrs(AS.getFnAttributes()); +      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);        FnAttrs.merge(B); @@ -144,32 +143,27 @@ bool LLParser::ValidateEndOfModule() {          FnAttrs.removeAttribute(Attribute::Alignment);        } -      AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, -                            AttributeSet::get(Context, -                                              AttributeSet::FunctionIndex, -                                              FnAttrs)); +      AS = AS.addAttributes( +          Context, AttributeList::FunctionIndex, +          AttributeList::get(Context, AttributeList::FunctionIndex, FnAttrs));        Fn->setAttributes(AS);      } else if (CallInst *CI = dyn_cast<CallInst>(V)) { -      AttributeSet AS = CI->getAttributes(); -      AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); -      AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, -                               AS.getFnAttributes()); +      AttributeList AS = CI->getAttributes(); +      AttrBuilder FnAttrs(AS.getFnAttributes()); +      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);        FnAttrs.merge(B); -      AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, -                            AttributeSet::get(Context, -                                              AttributeSet::FunctionIndex, -                                              FnAttrs)); +      AS = AS.addAttributes( +          Context, AttributeList::FunctionIndex, +          AttributeList::get(Context, AttributeList::FunctionIndex, FnAttrs));        CI->setAttributes(AS);      } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) { -      AttributeSet AS = II->getAttributes(); -      AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); -      AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, -                               AS.getFnAttributes()); +      AttributeList AS = II->getAttributes(); +      AttrBuilder FnAttrs(AS.getFnAttributes()); +      AS = AS.removeAttributes(Context, AttributeList::FunctionIndex);        FnAttrs.merge(B); -      AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, -                            AttributeSet::get(Context, -                                              AttributeSet::FunctionIndex, -                                              FnAttrs)); +      AS = AS.addAttributes( +          Context, AttributeList::FunctionIndex, +          AttributeList::get(Context, AttributeList::FunctionIndex, FnAttrs));        II->setAttributes(AS);      } else {        llvm_unreachable("invalid object with forward attribute group reference"); @@ -1855,6 +1849,34 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,    return false;  } +/// ParseOptionalCommaAddrSpace +///   ::= +///   ::= ',' addrspace(1) +/// +/// This returns with AteExtraComma set to true if it ate an excess comma at the +/// end. +bool LLParser::ParseOptionalCommaAddrSpace(unsigned &AddrSpace, +                                           LocTy &Loc, +                                           bool &AteExtraComma) { +  AteExtraComma = false; +  while (EatIfPresent(lltok::comma)) { +    // Metadata at the end is an early exit. +    if (Lex.getKind() == lltok::MetadataVar) { +      AteExtraComma = true; +      return false; +    } + +    Loc = Lex.getLoc(); +    if (Lex.getKind() != lltok::kw_addrspace) +      return Error(Lex.getLoc(), "expected metadata or 'addrspace'"); + +    if (ParseOptionalAddrSpace(AddrSpace)) +      return true; +  } + +  return false; +} +  bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,                                         Optional<unsigned> &HowManyArg) {    Lex.Lex(); @@ -2098,7 +2120,6 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,    if (ParseToken(lltok::lparen, "expected '(' in call"))      return true; -  unsigned AttrIndex = 1;    while (Lex.getKind() != lltok::rparen) {      // If this isn't the first argument, we need a comma.      if (!ArgList.empty() && @@ -2132,9 +2153,8 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,        if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))          return true;      } -    ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(), -                                                             AttrIndex++, -                                                             ArgAttrs))); +    ArgList.push_back(ParamInfo( +        ArgLoc, V, AttributeSet::get(V->getContext(), ArgAttrs)));    }    if (IsMustTailCall && InVarArgsFunc) @@ -2239,9 +2259,8 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,      if (!FunctionType::isValidArgumentType(ArgTy))        return Error(TypeLoc, "invalid type for function argument"); -    unsigned AttrIndex = 1; -    ArgList.emplace_back(TypeLoc, ArgTy, AttributeSet::get(ArgTy->getContext(), -                                                           AttrIndex++, Attrs), +    ArgList.emplace_back(TypeLoc, ArgTy, +                         AttributeSet::get(ArgTy->getContext(), Attrs),                           std::move(Name));      while (EatIfPresent(lltok::comma)) { @@ -2268,10 +2287,9 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,        if (!ArgTy->isFirstClassType())          return Error(TypeLoc, "invalid type for function argument"); -      ArgList.emplace_back( -          TypeLoc, ArgTy, -          AttributeSet::get(ArgTy->getContext(), AttrIndex++, Attrs), -          std::move(Name)); +      ArgList.emplace_back(TypeLoc, ArgTy, +                           AttributeSet::get(ArgTy->getContext(), Attrs), +                           std::move(Name));      }    } @@ -2295,7 +2313,7 @@ bool LLParser::ParseFunctionType(Type *&Result) {    for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {      if (!ArgList[i].Name.empty())        return Error(ArgList[i].Loc, "argument name invalid in function type"); -    if (ArgList[i].Attrs.hasAttributes(i + 1)) +    if (ArgList[i].Attrs.hasAttributes())        return Error(ArgList[i].Loc,                     "argument attributes invalid in function type");    } @@ -3908,7 +3926,8 @@ bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) {  /// ParseDIDerivedType:  ///   ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0,  ///                      line: 7, scope: !1, baseType: !2, size: 32, -///                      align: 32, offset: 0, flags: 0, extraData: !3) +///                      align: 32, offset: 0, flags: 0, extraData: !3, +///                      dwarfAddressSpace: 3)  bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) {  #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \    REQUIRED(tag, DwarfTagField, );                                              \ @@ -3921,14 +3940,20 @@ bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) {    OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \    OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX));                          \    OPTIONAL(flags, DIFlagField, );                                              \ -  OPTIONAL(extraData, MDField, ); +  OPTIONAL(extraData, MDField, );                                              \ +  OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX));    PARSE_MD_FIELDS();  #undef VISIT_MD_FIELDS +  Optional<unsigned> DWARFAddressSpace; +  if (dwarfAddressSpace.Val != UINT32_MAX) +    DWARFAddressSpace = dwarfAddressSpace.Val; +    Result = GET_OR_DISTINCT(DIDerivedType,                             (Context, tag.Val, name.Val, file.Val, line.Val,                              scope.Val, baseType.Val, size.Val, align.Val, -                            offset.Val, flags.Val, extraData.Val)); +                            offset.Val, DWARFAddressSpace, flags.Val, +                            extraData.Val));    return false;  } @@ -4029,7 +4054,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {    OPTIONAL(imports, MDField, );                                                \    OPTIONAL(macros, MDField, );                                                 \    OPTIONAL(dwoId, MDUnsignedField, );                                          \ -  OPTIONAL(splitDebugInlining, MDBoolField, = true); +  OPTIONAL(splitDebugInlining, MDBoolField, = true);                           \ +  OPTIONAL(debugInfoForProfiling, MDBoolField, = false);    PARSE_MD_FIELDS();  #undef VISIT_MD_FIELDS @@ -4037,7 +4063,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {        Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val,        runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val,        retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, -      splitDebugInlining.Val); +      splitDebugInlining.Val, debugInfoForProfiling.Val);    return false;  } @@ -4589,6 +4615,9 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {      C = cast<Constant>(V);      return false;    } +  case ValID::t_Null: +    C = Constant::getNullValue(Ty); +    return false;    default:      return Error(Loc, "expected a constant value");    } @@ -4735,25 +4764,14 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {    std::vector<Type*> ParamTypeList;    SmallVector<AttributeSet, 8> Attrs; -  if (RetAttrs.hasAttributes()) -    Attrs.push_back(AttributeSet::get(RetType->getContext(), -                                      AttributeSet::ReturnIndex, -                                      RetAttrs)); -    for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {      ParamTypeList.push_back(ArgList[i].Ty); -    if (ArgList[i].Attrs.hasAttributes(i + 1)) { -      AttrBuilder B(ArgList[i].Attrs, i + 1); -      Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); -    } +    Attrs.push_back(ArgList[i].Attrs);    } -  if (FuncAttrs.hasAttributes()) -    Attrs.push_back(AttributeSet::get(RetType->getContext(), -                                      AttributeSet::FunctionIndex, -                                      FuncAttrs)); - -  AttributeSet PAL = AttributeSet::get(Context, Attrs); +  AttributeList PAL = +      AttributeList::get(Context, AttributeSet::get(Context, FuncAttrs), +                         AttributeSet::get(Context, RetAttrs), Attrs);    if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy())      return Error(RetTypeLoc, "functions with 'sret' argument must return void"); @@ -5363,13 +5381,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {      return true;    // Set up the Attribute for the function. -  SmallVector<AttributeSet, 8> Attrs; -  if (RetAttrs.hasAttributes()) -    Attrs.push_back(AttributeSet::get(RetType->getContext(), -                                      AttributeSet::ReturnIndex, -                                      RetAttrs)); - -  SmallVector<Value*, 8> Args; +  SmallVector<Value *, 8> Args; +  SmallVector<AttributeSet, 8> ArgAttrs;    // Loop through FunctionType's arguments and ensure they are specified    // correctly.  Also, gather any parameter attributes. @@ -5387,26 +5400,19 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {        return Error(ArgList[i].Loc, "argument is not of expected type '" +                     getTypeString(ExpectedTy) + "'");      Args.push_back(ArgList[i].V); -    if (ArgList[i].Attrs.hasAttributes(i + 1)) { -      AttrBuilder B(ArgList[i].Attrs, i + 1); -      Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); -    } +    ArgAttrs.push_back(ArgList[i].Attrs);    }    if (I != E)      return Error(CallLoc, "not enough parameters specified for call"); -  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)); -  } +  if (FnAttrs.hasAlignmentAttr()) +    return Error(CallLoc, "invoke instructions may not have an alignment");    // Finish off the Attribute and check them -  AttributeSet PAL = AttributeSet::get(Context, Attrs); +  AttributeList PAL = +      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs), +                         AttributeSet::get(Context, RetAttrs), ArgAttrs);    InvokeInst *II =        InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args, BundleList); @@ -5968,10 +5974,6 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,    // Set up the Attribute for the function.    SmallVector<AttributeSet, 8> Attrs; -  if (RetAttrs.hasAttributes()) -    Attrs.push_back(AttributeSet::get(RetType->getContext(), -                                      AttributeSet::ReturnIndex, -                                      RetAttrs));    SmallVector<Value*, 8> Args; @@ -5991,26 +5993,19 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,        return Error(ArgList[i].Loc, "argument is not of expected type '" +                     getTypeString(ExpectedTy) + "'");      Args.push_back(ArgList[i].V); -    if (ArgList[i].Attrs.hasAttributes(i + 1)) { -      AttrBuilder B(ArgList[i].Attrs, i + 1); -      Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); -    } +    Attrs.push_back(ArgList[i].Attrs);    }    if (I != E)      return Error(CallLoc, "not enough parameters specified for call"); -  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)); -  } +  if (FnAttrs.hasAlignmentAttr()) +    return Error(CallLoc, "call instructions may not have an alignment");    // Finish off the Attribute and check them -  AttributeSet PAL = AttributeSet::get(Context, Attrs); +  AttributeList PAL = +      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs), +                         AttributeSet::get(Context, RetAttrs), Attrs);    CallInst *CI = CallInst::Create(Ty, Callee, Args, BundleList);    CI->setTailCallKind(TCK); @@ -6032,8 +6027,9 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,  ///       (',' 'align' i32)?  int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {    Value *Size = nullptr; -  LocTy SizeLoc, TyLoc; +  LocTy SizeLoc, TyLoc, ASLoc;    unsigned Alignment = 0; +  unsigned AddrSpace = 0;    Type *Ty = nullptr;    bool IsInAlloca = EatIfPresent(lltok::kw_inalloca); @@ -6047,12 +6043,21 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {    bool AteExtraComma = false;    if (EatIfPresent(lltok::comma)) {      if (Lex.getKind() == lltok::kw_align) { -      if (ParseOptionalAlignment(Alignment)) return true; +      if (ParseOptionalAlignment(Alignment)) +        return true; +      if (ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma)) +        return true; +    } else if (Lex.getKind() == lltok::kw_addrspace) { +      ASLoc = Lex.getLoc(); +      if (ParseOptionalAddrSpace(AddrSpace)) +        return true;      } else if (Lex.getKind() == lltok::MetadataVar) {        AteExtraComma = true;      } else {        if (ParseTypeAndValue(Size, SizeLoc, PFS) || -          ParseOptionalCommaAlign(Alignment, AteExtraComma)) +          ParseOptionalCommaAlign(Alignment, AteExtraComma) || +          (!AteExtraComma && +           ParseOptionalCommaAddrSpace(AddrSpace, ASLoc, AteExtraComma)))          return true;      }    } @@ -6060,7 +6065,14 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {    if (Size && !Size->getType()->isIntegerTy())      return Error(SizeLoc, "element count must have integer type"); -  AllocaInst *AI = new AllocaInst(Ty, Size, Alignment); +  const DataLayout &DL = M->getDataLayout(); +  unsigned AS = DL.getAllocaAddrSpace(); +  if (AS != AddrSpace) { +    // TODO: In the future it should be possible to specify addrspace per-alloca. +    return Error(ASLoc, "address space must match datalayout"); +  } + +  AllocaInst *AI = new AllocaInst(Ty, AS, Size, Alignment);    AI->setUsedWithInAlloca(IsInAlloca);    AI->setSwiftError(IsSwiftError);    Inst = AI; | 
