X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=fc7fceb2a2668fdc12676b5cae0ee4de2cd6a78a;hp=6c2cd08e580bf0cf3ae288abd671e8a435f1d674;hb=0e99876efe5c2cbea63ec91c74ec923c3fd193e5;hpb=4a45f0871a26e65a48a74dbb277c70f662344235 diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 6c2cd08e580..fc7fceb2a26 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -13,6 +13,7 @@ #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" @@ -48,7 +49,9 @@ bool LLParser::Run() { ValidateEndOfModule(); } -bool LLParser::parseStandaloneConstantValue(Constant *&C) { +bool LLParser::parseStandaloneConstantValue(Constant *&C, + const SlotMapping *Slots) { + restoreParsingState(Slots); Lex.Lex(); Type *Ty = nullptr; @@ -59,6 +62,19 @@ bool LLParser::parseStandaloneConstantValue(Constant *&C) { return false; } +void LLParser::restoreParsingState(const SlotMapping *Slots) { + if (!Slots) + return; + NumberedVals = Slots->GlobalValues; + NumberedMetadata = Slots->MetadataNodes; + for (const auto &I : Slots->NamedTypes) + NamedTypes.insert( + std::make_pair(I.getKey(), std::make_pair(I.second, LocTy()))); + for (const auto &I : Slots->Types) + NumberedTypes.insert( + std::make_pair(I.first, std::make_pair(I.second, LocTy()))); +} + /// ValidateEndOfModule - Do final validity and sanity checks at the end of the /// module. bool LLParser::ValidateEndOfModule() { @@ -180,6 +196,10 @@ bool LLParser::ValidateEndOfModule() { // the mapping from LLParser as it doesn't need it anymore. Slots->GlobalValues = std::move(NumberedVals); Slots->MetadataNodes = std::move(NumberedMetadata); + for (const auto &I : NamedTypes) + Slots->NamedTypes.insert(std::make_pair(I.getKey(), I.second.first)); + for (const auto &I : NumberedTypes) + Slots->Types.insert(std::make_pair(I.first, I.second.first)); return false; } @@ -914,14 +934,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, } // Target-dependent attributes: case lltok::StringConstant: { - std::string Attr = Lex.getStrVal(); - Lex.Lex(); - std::string Val; - if (EatIfPresent(lltok::equal) && - ParseStringConstant(Val)) + if (ParseStringAttribute(B)) return true; - - B.addAttribute(Attr, Val); continue; } @@ -1228,6 +1242,19 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { ParseToken(lltok::rparen, "expected ')' in address space"); } +/// ParseStringAttribute +/// := StringConstant +/// := StringConstant '=' StringConstant +bool LLParser::ParseStringAttribute(AttrBuilder &B) { + std::string Attr = Lex.getStrVal(); + Lex.Lex(); + std::string Val; + if (EatIfPresent(lltok::equal) && ParseStringConstant(Val)) + return true; + B.addAttribute(Attr, Val); + return false; +} + /// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes. bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { bool HaveError = false; @@ -1239,6 +1266,11 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { switch (Token) { default: // End of attributes. return HaveError; + case lltok::StringConstant: { + if (ParseStringAttribute(B)) + return true; + continue; + } case lltok::kw_align: { unsigned Alignment; if (ParseOptionalAlignment(Alignment)) @@ -1320,6 +1352,11 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { switch (Token) { default: // End of attributes. return HaveError; + case lltok::StringConstant: { + if (ParseStringAttribute(B)) + return true; + continue; + } case lltok::kw_dereferenceable: { uint64_t Bytes; if (ParseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes)) @@ -2441,9 +2478,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ParseToken(lltok::rbrace, "expected end of struct constant")) return true; - ID.ConstantStructElts = new Constant*[Elts.size()]; + ID.ConstantStructElts = make_unique(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; } @@ -2462,8 +2500,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (isPackedStruct) { - ID.ConstantStructElts = new Constant*[Elts.size()]; - memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0])); + ID.ConstantStructElts = make_unique(Elts.size()); + memcpy(ID.ConstantStructElts.get(), Elts.data(), + Elts.size() * sizeof(Elts[0])); ID.UIntVal = Elts.size(); ID.Kind = ValID::t_PackedConstantStruct; return false; @@ -2902,7 +2941,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { } } - SmallPtrSet Visited; + SmallPtrSet Visited; if (!Indices.empty() && !Ty->isSized(&Visited)) return Error(ID.Loc, "base element of getelementptr must be sized"); @@ -3582,6 +3621,9 @@ bool LLParser::ParseDIFile(MDNode *&Result, bool IsDistinct) { /// enums: !1, retainedTypes: !2, subprograms: !3, /// globals: !4, imports: !5, dwoId: 0x0abcd) bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { + if (!IsDistinct) + return Lex.Error("missing 'distinct', required for !DICompileUnit"); + #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(language, DwarfLangField, ); \ REQUIRED(file, MDField, (/* AllowNull */ false)); \ @@ -3600,12 +3642,10 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DICompileUnit, - (Context, language.Val, file.Val, producer.Val, - isOptimized.Val, flags.Val, runtimeVersion.Val, - splitDebugFilename.Val, emissionKind.Val, enums.Val, - retainedTypes.Val, subprograms.Val, globals.Val, - imports.Val, dwoId.Val)); + Result = DICompileUnit::getDistinct( + Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val, + runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, + retainedTypes.Val, subprograms.Val, globals.Val, imports.Val, dwoId.Val); return false; } @@ -3773,24 +3813,25 @@ bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { } /// 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; } @@ -4066,8 +4107,8 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, 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; @@ -5005,13 +5046,24 @@ bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { } /// ParseCatchRet -/// ::= 'catchret' TypeAndValue +/// ::= 'catchret' ('void' | TypeAndValue) 'to' TypeAndValue bool LLParser::ParseCatchRet(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; + BasicBlock *BB; - if (ParseTypeAndBasicBlock(BB, PFS)) + if (ParseToken(lltok::kw_to, "expected 'to' in catchret") || + ParseTypeAndBasicBlock(BB, PFS)) return true; - Inst = CatchReturnInst::Create(BB); + Inst = CatchReturnInst::Create(BB, RetVal); return false; } @@ -5813,7 +5865,7 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.push_back(Val); } - SmallPtrSet Visited; + SmallPtrSet Visited; if (!Indices.empty() && !Ty->isSized(&Visited)) return Error(Loc, "base element of getelementptr must be sized");