using namespace llvm;
static std::string getTypeString(Type *T) {
- std::string Result;
- raw_string_ostream Tmp(Result);
- Tmp << *T;
- return Tmp.str();
+ string_ostream Result;
+ Result << *T;
+ return Result.str();
}
/// Run: module ::= toplevelentity*
case lltok::kw_appending: // OptionalLinkage
case lltok::kw_common: // OptionalLinkage
case lltok::kw_extern_weak: // OptionalLinkage
- case lltok::kw_external: { // OptionalLinkage
+ case lltok::kw_external: // OptionalLinkage
+ case lltok::kw_default: // OptionalVisibility
+ case lltok::kw_hidden: // OptionalVisibility
+ case lltok::kw_protected: // OptionalVisibility
+ case lltok::kw_dllimport: // OptionalDLLStorageClass
+ case lltok::kw_dllexport: // OptionalDLLStorageClass
+ case lltok::kw_thread_local: // OptionalThreadLocal
+ case lltok::kw_addrspace: // OptionalAddrSpace
+ case lltok::kw_constant: // GlobalType
+ case lltok::kw_global: { // GlobalType
unsigned Linkage, Visibility, DLLStorageClass;
- if (ParseOptionalLinkage(Linkage) ||
+ bool UnnamedAddr;
+ GlobalVariable::ThreadLocalMode TLM;
+ bool HasLinkage;
+ if (ParseOptionalLinkage(Linkage, HasLinkage) ||
ParseOptionalVisibility(Visibility) ||
ParseOptionalDLLStorageClass(DLLStorageClass) ||
- ParseGlobal("", SMLoc(), Linkage, true, Visibility, DLLStorageClass))
- return true;
- break;
- }
- case lltok::kw_default: // OptionalVisibility
- case lltok::kw_hidden: // OptionalVisibility
- case lltok::kw_protected: { // OptionalVisibility
- unsigned Visibility, DLLStorageClass;
- if (ParseOptionalVisibility(Visibility) ||
- ParseOptionalDLLStorageClass(DLLStorageClass) ||
- ParseGlobal("", SMLoc(), 0, false, Visibility, DLLStorageClass))
+ ParseOptionalThreadLocal(TLM) ||
+ parseOptionalUnnamedAddr(UnnamedAddr) ||
+ ParseGlobal("", SMLoc(), Linkage, HasLinkage, Visibility,
+ DLLStorageClass, TLM, UnnamedAddr))
return true;
break;
}
- case lltok::kw_thread_local: // OptionalThreadLocal
- case lltok::kw_addrspace: // OptionalAddrSpace
- case lltok::kw_constant: // GlobalType
- case lltok::kw_global: // GlobalType
- if (ParseGlobal("", SMLoc(), 0, false, 0, 0)) return true;
- break;
-
case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break;
}
}
bool HasLinkage;
unsigned Linkage, Visibility, DLLStorageClass;
+ GlobalVariable::ThreadLocalMode TLM;
+ bool UnnamedAddr;
if (ParseOptionalLinkage(Linkage, HasLinkage) ||
ParseOptionalVisibility(Visibility) ||
- ParseOptionalDLLStorageClass(DLLStorageClass))
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
+ ParseOptionalThreadLocal(TLM) ||
+ parseOptionalUnnamedAddr(UnnamedAddr))
return true;
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
- DLLStorageClass);
- return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
+ DLLStorageClass, TLM, UnnamedAddr);
+ return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM,
+ UnnamedAddr);
}
/// 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))
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
+ ParseOptionalThreadLocal(TLM) ||
+ parseOptionalUnnamedAddr(UnnamedAddr))
return true;
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
- DLLStorageClass);
- return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
+ DLLStorageClass, TLM, UnnamedAddr);
+ return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM,
+ UnnamedAddr);
}
// MDString:
bool LLParser::ParseMDString(MDString *&Result) {
std::string Str;
if (ParseStringConstant(Str)) return true;
+ llvm::UpgradeMDStringConstant(Str);
Result = MDString::get(Context, Str);
return false;
}
}
/// ParseAlias:
-/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias'
+/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalUnNammedAddr 'alias'
/// OptionalLinkage Aliasee
-/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias'
-/// OptionalLinkage OptionalAddrSpace Type, Aliasee
///
/// Aliasee
/// ::= TypeAndValue
///
-/// Everything through DLL storage class has already been parsed.
+/// Everything through OptionalUnNammedAddr has already been parsed.
///
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
- unsigned Visibility, unsigned DLLStorageClass) {
+ unsigned Visibility, unsigned DLLStorageClass,
+ GlobalVariable::ThreadLocalMode TLM,
+ bool UnnamedAddr) {
assert(Lex.getKind() == lltok::kw_alias);
Lex.Lex();
LocTy LinkageLoc = Lex.getLoc();
return Error(LinkageLoc,
"symbol with local linkage must have default visibility");
- bool HasAddrSpace = Lex.getKind() == lltok::kw_addrspace;
- unsigned AddrSpace;
- LocTy AddrSpaceLoc = Lex.getLoc();
- if (ParseOptionalAddrSpace(AddrSpace))
- return true;
-
- LocTy TyLoc = Lex.getLoc();
- Type *Ty = nullptr;
- if (ParseType(Ty))
- return true;
-
- bool DifferentType = EatIfPresent(lltok::comma);
- if (HasAddrSpace && !DifferentType)
- return Error(AddrSpaceLoc, "A type is required if addrspace is given");
-
- Type *AliaseeType = nullptr;
- if (DifferentType) {
- if (ParseType(AliaseeType))
+ Constant *Aliasee;
+ LocTy AliaseeLoc = Lex.getLoc();
+ if (Lex.getKind() != lltok::kw_bitcast &&
+ Lex.getKind() != lltok::kw_getelementptr &&
+ Lex.getKind() != lltok::kw_addrspacecast &&
+ Lex.getKind() != lltok::kw_inttoptr) {
+ if (ParseGlobalTypeAndValue(Aliasee))
return true;
} else {
- AliaseeType = Ty;
- auto *PTy = dyn_cast<PointerType>(Ty);
- if (!PTy)
- return Error(TyLoc, "An alias must have pointer type");
- Ty = PTy->getElementType();
- AddrSpace = PTy->getAddressSpace();
+ // The bitcast dest type is not present, it is implied by the dest type.
+ ValID ID;
+ if (ParseValID(ID))
+ return true;
+ if (ID.Kind != ValID::t_Constant)
+ return Error(AliaseeLoc, "invalid aliasee");
+ Aliasee = ID.ConstantVal;
}
- LocTy AliaseeLoc = Lex.getLoc();
- Constant *C;
- if (ParseGlobalValue(AliaseeType, C))
- return true;
-
- auto *Aliasee = dyn_cast<GlobalObject>(C);
- if (!Aliasee)
- return Error(AliaseeLoc, "Alias must point to function or variable");
-
- assert(Aliasee->getType()->isPointerTy());
+ Type *AliaseeType = Aliasee->getType();
+ auto *PTy = dyn_cast<PointerType>(AliaseeType);
+ if (!PTy)
+ return Error(AliaseeLoc, "An alias must have pointer type");
+ Type *Ty = PTy->getElementType();
+ unsigned AddrSpace = PTy->getAddressSpace();
// Okay, create the alias but do not insert it into the module yet.
std::unique_ptr<GlobalAlias> GA(
- new GlobalAlias(Ty, (GlobalValue::LinkageTypes)Linkage, Name, Aliasee,
- /*Parent*/ nullptr, AddrSpace));
+ GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage,
+ Name, Aliasee, /*Parent*/ nullptr));
+ 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.
// If they agree, just RAUW the old value with the alias and remove the
// forward ref info.
- for (auto *User : Val->users()) {
- if (auto *GA = dyn_cast<GlobalAlias>(User))
- return Error(NameLoc, "Alias is pointed by alias " + GA->getName());
- }
-
Val->replaceAllUsesWith(GA.get());
Val->eraseFromParent();
ForwardRefVals.erase(I);
/// 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 OptionalDLLStorageClass 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) {
+ unsigned Visibility, unsigned DLLStorageClass,
+ 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;
- GlobalVariable::ThreadLocalMode TLM;
- LocTy UnnamedAddrLoc;
+ bool IsConstant, IsExternallyInitialized;
LocTy IsExternallyInitializedLoc;
LocTy TyLoc;
Type *Ty = nullptr;
- if (ParseOptionalThreadLocal(TLM) ||
- ParseOptionalAddrSpace(AddrSpace) ||
- ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
- &UnnamedAddrLoc) ||
+ if (ParseOptionalAddrSpace(AddrSpace) ||
ParseOptionalToken(lltok::kw_externally_initialized,
IsExternallyInitialized,
&IsExternallyInitializedLoc) ||
case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
+ case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
case lltok::kw_nest:
case lltok::kw_noalias:
case lltok::kw_nocapture:
+ case lltok::kw_nonnull:
case lltok::kw_returned:
case lltok::kw_sret:
HaveError |=
case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break;
+ case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
case lltok::kw_returned: B.addAttribute(Attribute::Returned); break;
case lltok::kw_alwaysinline:
case lltok::kw_builtin:
case lltok::kw_inlinehint:
+ case lltok::kw_jumptable:
case lltok::kw_minsize:
case lltok::kw_naked:
case lltok::kw_nobuiltin:
return HaveError;
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;
case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
case lltok::kw_builtin:
case lltok::kw_cold:
case lltok::kw_inlinehint:
+ case lltok::kw_jumptable:
case lltok::kw_minsize:
case lltok::kw_naked:
case lltok::kw_nobuiltin:
else
return TokError("expected 'catch' or 'filter' clause type");
- Value *V; LocTy VLoc;
+ Value *V;
+ LocTy VLoc;
if (ParseTypeAndValue(V, VLoc, PFS)) {
delete LP;
return true;
Error(VLoc, "'filter' clause has an invalid type");
}
- LP->addClause(V);
+ LP->addClause(cast<Constant>(V));
}
Inst = LP;
}
/// 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;
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;
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;
}