X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAsmParser%2FLLParser.cpp;h=0fa53019df1726841f14cf75b8c1f6f942d02cb2;hb=08f77a9f422e96110d8400e4caaf6a51be49a1f3;hp=f77abaca17f946a5626724da4588baf8aa9db876;hpb=5d0f7af3dc42d7bc843858317fba3bb91c44d68f;p=oota-llvm.git diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index f77abaca17f..0fa53019df1 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -163,6 +163,11 @@ bool LLParser::ValidateEndOfModule() { return Error(I->second.second, "use of undefined type named '" + I->getKey() + "'"); + if (!ForwardRefComdats.empty()) + return Error(ForwardRefComdats.begin()->second, + "use of undefined comdat '$" + + ForwardRefComdats.begin()->first + "'"); + if (!ForwardRefVals.empty()) return Error(ForwardRefVals.begin()->second.second, "use of undefined value '@" + ForwardRefVals.begin()->first + @@ -238,6 +243,7 @@ bool LLParser::ParseTopLevelEntities() { case lltok::LocalVar: if (ParseNamedType()) return true; break; case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break; case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break; + case lltok::ComdatVar: if (parseComdat()) return true; break; case lltok::exclaim: if (ParseStandaloneMetadata()) return true; break; case lltok::MetadataVar:if (ParseNamedMetadata()) return true; break; @@ -248,8 +254,6 @@ bool LLParser::ParseTopLevelEntities() { // ('constant'|'global') ... case lltok::kw_private: // OptionalLinkage case lltok::kw_internal: // OptionalLinkage - case lltok::kw_linker_private: // Obsolete OptionalLinkage - case lltok::kw_linker_private_weak: // Obsolete OptionalLinkage case lltok::kw_weak: // OptionalLinkage case lltok::kw_weak_odr: // OptionalLinkage case lltok::kw_linkonce: // OptionalLinkage @@ -268,14 +272,16 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_constant: // GlobalType case lltok::kw_global: { // GlobalType unsigned Linkage, Visibility, DLLStorageClass; + bool UnnamedAddr; GlobalVariable::ThreadLocalMode TLM; bool HasLinkage; if (ParseOptionalLinkage(Linkage, HasLinkage) || ParseOptionalVisibility(Visibility) || ParseOptionalDLLStorageClass(DLLStorageClass) || ParseOptionalThreadLocal(TLM) || + parseOptionalUnnamedAddr(UnnamedAddr) || ParseGlobal("", SMLoc(), Linkage, HasLinkage, Visibility, - DLLStorageClass, TLM)) + DLLStorageClass, TLM, UnnamedAddr)) return true; break; } @@ -467,16 +473,19 @@ bool LLParser::ParseUnnamedGlobal() { bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; GlobalVariable::ThreadLocalMode TLM; + bool UnnamedAddr; if (ParseOptionalLinkage(Linkage, HasLinkage) || ParseOptionalVisibility(Visibility) || ParseOptionalDLLStorageClass(DLLStorageClass) || - ParseOptionalThreadLocal(TLM)) + ParseOptionalThreadLocal(TLM) || + parseOptionalUnnamedAddr(UnnamedAddr)) return true; - if (HasLinkage || Lex.getKind() != lltok::kw_alias) + if (Lex.getKind() != lltok::kw_alias) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass, TLM); - return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM); + DLLStorageClass, TLM, UnnamedAddr); + return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM, + UnnamedAddr); } /// ParseNamedGlobal: @@ -492,17 +501,71 @@ bool LLParser::ParseNamedGlobal() { bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; GlobalVariable::ThreadLocalMode TLM; + bool UnnamedAddr; if (ParseToken(lltok::equal, "expected '=' in global variable") || ParseOptionalLinkage(Linkage, HasLinkage) || ParseOptionalVisibility(Visibility) || ParseOptionalDLLStorageClass(DLLStorageClass) || - ParseOptionalThreadLocal(TLM)) + ParseOptionalThreadLocal(TLM) || + parseOptionalUnnamedAddr(UnnamedAddr)) return true; - if (HasLinkage || Lex.getKind() != lltok::kw_alias) + if (Lex.getKind() != lltok::kw_alias) return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility, - DLLStorageClass, TLM); - return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM); + DLLStorageClass, TLM, UnnamedAddr); + + return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM, + UnnamedAddr); +} + +bool LLParser::parseComdat() { + assert(Lex.getKind() == lltok::ComdatVar); + std::string Name = Lex.getStrVal(); + LocTy NameLoc = Lex.getLoc(); + Lex.Lex(); + + if (ParseToken(lltok::equal, "expected '=' here")) + return true; + + if (ParseToken(lltok::kw_comdat, "expected comdat keyword")) + return TokError("expected comdat type"); + + Comdat::SelectionKind SK; + switch (Lex.getKind()) { + default: + return TokError("unknown selection kind"); + case lltok::kw_any: + SK = Comdat::Any; + break; + case lltok::kw_exactmatch: + SK = Comdat::ExactMatch; + break; + case lltok::kw_largest: + SK = Comdat::Largest; + break; + case lltok::kw_noduplicates: + SK = Comdat::NoDuplicates; + break; + case lltok::kw_samesize: + SK = Comdat::SameSize; + break; + } + Lex.Lex(); + + // See if the comdat was forward referenced, if so, use the comdat. + Module::ComdatSymTabType &ComdatSymTab = M->getComdatSymbolTable(); + Module::ComdatSymTabType::iterator I = ComdatSymTab.find(Name); + if (I != ComdatSymTab.end() && !ForwardRefComdats.erase(Name)) + return Error(NameLoc, "redefinition of comdat '$" + Name + "'"); + + Comdat *C; + if (I != ComdatSymTab.end()) + C = &I->second; + else + C = M->getOrInsertComdat(Name); + C->setSelectionKind(SK); + + return false; } // MDString: @@ -510,6 +573,7 @@ bool LLParser::ParseNamedGlobal() { bool LLParser::ParseMDString(MDString *&Result) { std::string Str; if (ParseStringConstant(Str)) return true; + llvm::UpgradeMDStringConstant(Str); Result = MDString::get(Context, Str); return false; } @@ -628,31 +692,29 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { } /// ParseAlias: -/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal 'alias' OptionalLinkage Aliasee +/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility +/// OptionalDLLStorageClass OptionalThreadLocal +/// OptionalUnNammedAddr 'alias' Aliasee /// /// Aliasee /// ::= TypeAndValue /// -/// Everything through OptionalThreadLocal has already been parsed. +/// Everything through OptionalUnNammedAddr has already been parsed. /// -bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, +bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility, unsigned DLLStorageClass, - GlobalVariable::ThreadLocalMode TLM) { + GlobalVariable::ThreadLocalMode TLM, + bool UnnamedAddr) { assert(Lex.getKind() == lltok::kw_alias); Lex.Lex(); - LocTy LinkageLoc = Lex.getLoc(); - unsigned L; - if (ParseOptionalLinkage(L)) - return true; GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L; if(!GlobalAlias::isValidLinkage(Linkage)) - return Error(LinkageLoc, "invalid linkage type for alias"); + return Error(NameLoc, "invalid linkage type for alias"); if (!isValidVisibilityForLinkage(Visibility, L)) - return Error(LinkageLoc, + return Error(NameLoc, "symbol with local linkage must have default visibility"); Constant *Aliasee; @@ -687,6 +749,7 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, GA->setThreadLocalMode(TLM); GA->setVisibility((GlobalValue::VisibilityTypes)Visibility); GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass); + GA->setUnnamedAddr(UnnamedAddr); // See if this value already exists in the symbol table. If so, it is either // a redefinition or a definition of a forward reference. @@ -723,33 +786,31 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, /// ParseGlobal /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr +/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const /// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass -/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr +/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace /// OptionalExternallyInitialized GlobalType Type Const /// -/// Everything up to and including OptionalThreadLocal has been parsed +/// Everything up to and including OptionalUnNammedAddr has been parsed /// already. /// bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility, unsigned DLLStorageClass, - GlobalVariable::ThreadLocalMode TLM) { + GlobalVariable::ThreadLocalMode TLM, + bool UnnamedAddr) { if (!isValidVisibilityForLinkage(Visibility, Linkage)) return Error(NameLoc, "symbol with local linkage must have default visibility"); unsigned AddrSpace; - bool IsConstant, UnnamedAddr, IsExternallyInitialized; - LocTy UnnamedAddrLoc; + bool IsConstant, IsExternallyInitialized; LocTy IsExternallyInitializedLoc; LocTy TyLoc; Type *Ty = nullptr; if (ParseOptionalAddrSpace(AddrSpace) || - ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, - &UnnamedAddrLoc) || ParseOptionalToken(lltok::kw_externally_initialized, IsExternallyInitialized, &IsExternallyInitializedLoc) || @@ -828,7 +889,13 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, if (ParseOptionalAlignment(Alignment)) return true; GV->setAlignment(Alignment); } else { - TokError("unknown global variable property!"); + Comdat *C; + if (parseOptionalComdat(C)) + return true; + if (C) + GV->setComdat(C); + else + return TokError("unknown global variable property!"); } } @@ -980,6 +1047,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, "invalid use of attribute on a function"); break; case lltok::kw_byval: + case lltok::kw_dereferenceable: case lltok::kw_inalloca: case lltok::kw_nest: case lltok::kw_noalias: @@ -1086,6 +1154,24 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { } +//===----------------------------------------------------------------------===// +// Comdat Reference/Resolution Routines. +//===----------------------------------------------------------------------===// + +Comdat *LLParser::getComdat(const std::string &Name, LocTy Loc) { + // Look this name up in the comdat symbol table. + Module::ComdatSymTabType &ComdatSymTab = M->getComdatSymbolTable(); + Module::ComdatSymTabType::iterator I = ComdatSymTab.find(Name); + if (I != ComdatSymTab.end()) + return &I->second; + + // Otherwise, create a new forward reference for this value and remember it. + Comdat *C = M->getOrInsertComdat(Name); + ForwardRefComdats[Name] = Loc; + return C; +} + + //===----------------------------------------------------------------------===// // Helper Routines. //===----------------------------------------------------------------------===// @@ -1122,6 +1208,16 @@ bool LLParser::ParseUInt32(unsigned &Val) { return false; } +/// ParseUInt64 +/// ::= uint64 +bool LLParser::ParseUInt64(uint64_t &Val) { + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) + return TokError("expected integer"); + Val = Lex.getAPSIntVal().getLimitedValue(); + Lex.Lex(); + return false; +} + /// ParseTLSModel /// := 'localdynamic' /// := 'initialexec' @@ -1194,6 +1290,13 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { continue; } case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break; + case lltok::kw_dereferenceable: { + uint64_t Bytes; + if (ParseOptionalDereferenceableBytes(Bytes)) + return true; + B.addDereferenceableAttr(Bytes); + continue; + } case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break; case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; @@ -1251,6 +1354,13 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { switch (Token) { default: // End of attributes. return HaveError; + case lltok::kw_dereferenceable: { + uint64_t Bytes; + if (ParseOptionalDereferenceableBytes(Bytes)) + return true; + B.addDereferenceableAttr(Bytes); + continue; + } case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break; @@ -1319,10 +1429,6 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { /// ::= 'common' /// ::= 'extern_weak' /// ::= 'external' -/// -/// Deprecated Values: -/// ::= 'linker_private' -/// ::= 'linker_private_weak' bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { HasLinkage = false; switch (Lex.getKind()) { @@ -1340,15 +1446,6 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { case lltok::kw_common: Res = GlobalValue::CommonLinkage; break; case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break; case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; - - case lltok::kw_linker_private: - case lltok::kw_linker_private_weak: - Lex.Warning("'" + Lex.getStrVal() + "' is deprecated, treating as" - " PrivateLinkage"); - Lex.Lex(); - // treat linker_private and linker_private_weak as PrivateLinkage - Res = GlobalValue::PrivateLinkage; - return false; } Lex.Lex(); HasLinkage = true; @@ -1516,6 +1613,26 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { return false; } +/// ParseOptionalDereferenceableBytes +/// ::= /* empty */ +/// ::= 'dereferenceable' '(' 4 ')' +bool LLParser::ParseOptionalDereferenceableBytes(uint64_t &Bytes) { + Bytes = 0; + if (!EatIfPresent(lltok::kw_dereferenceable)) + return false; + LocTy ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::lparen)) + return Error(ParenLoc, "expected '('"); + LocTy DerefLoc = Lex.getLoc(); + if (ParseUInt64(Bytes)) return true; + ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::rparen)) + return Error(ParenLoc, "expected ')'"); + if (!Bytes) + return Error(DerefLoc, "dereferenceable bytes must be non-zero"); + return false; +} + /// ParseOptionalCommaAlign /// ::= /// ::= ',' align 4 @@ -2132,7 +2249,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, } // Don't make placeholders with invalid type. - if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType()) { P.Error(Loc, "invalid use of a non-first-class type"); return nullptr; } @@ -2173,7 +2290,7 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, return nullptr; } - if (!Ty->isFirstClassType() && !Ty->isLabelTy()) { + if (!Ty->isFirstClassType()) { P.Error(Loc, "invalid use of a non-first-class type"); return nullptr; } @@ -2780,6 +2897,19 @@ bool LLParser::ParseGlobalTypeAndValue(Constant *&V) { ParseGlobalValue(Ty, V); } +bool LLParser::parseOptionalComdat(Comdat *&C) { + C = nullptr; + if (!EatIfPresent(lltok::kw_comdat)) + return false; + if (Lex.getKind() != lltok::ComdatVar) + return TokError("expected comdat variable"); + LocTy Loc = Lex.getLoc(); + StringRef Name = Lex.getStrVal(); + C = getComdat(Name, Loc); + Lex.Lex(); + return false; +} + /// ParseGlobalValueVector /// ::= /*empty*/ /// ::= TypeAndValue (',' TypeAndValue)* @@ -3080,6 +3210,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { bool UnnamedAddr; LocTy UnnamedAddrLoc; Constant *Prefix = nullptr; + Comdat *C; if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, @@ -3088,6 +3219,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { BuiltinLoc) || (EatIfPresent(lltok::kw_section) && ParseStringConstant(Section)) || + parseOptionalComdat(C) || ParseOptionalAlignment(Alignment) || (EatIfPresent(lltok::kw_gc) && ParseStringConstant(GC)) || @@ -3190,6 +3322,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn->setUnnamedAddr(UnnamedAddr); Fn->setAlignment(Alignment); Fn->setSection(Section); + Fn->setComdat(C); if (!GC.empty()) Fn->setGC(GC.c_str()); Fn->setPrefixData(Prefix); ForwardRefAttrGroups[Fn] = FwdRefAttrGrps; @@ -4247,8 +4380,8 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) { } /// ParseCmpXchg -/// ::= 'cmpxchg' 'volatile'? TypeAndValue ',' TypeAndValue ',' TypeAndValue -/// 'singlethread'? AtomicOrdering AtomicOrdering +/// ::= 'cmpxchg' 'weak'? 'volatile'? TypeAndValue ',' TypeAndValue ',' +/// TypeAndValue 'singlethread'? AtomicOrdering AtomicOrdering int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc; bool AteExtraComma = false; @@ -4256,6 +4389,10 @@ int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { AtomicOrdering FailureOrdering = NotAtomic; SynchronizationScope Scope = CrossThread; bool isVolatile = false; + bool isWeak = false; + + if (EatIfPresent(lltok::kw_weak)) + isWeak = true; if (EatIfPresent(lltok::kw_volatile)) isVolatile = true; @@ -4288,9 +4425,10 @@ int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { return Error(NewLoc, "cmpxchg operand must be power-of-two byte-sized" " integer"); - AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, - FailureOrdering, Scope); + AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst( + Ptr, Cmp, New, SuccessOrdering, FailureOrdering, Scope); CXI->setVolatile(isVolatile); + CXI->setWeak(isWeak); Inst = CXI; return AteExtraComma ? InstExtraComma : InstNormal; }