#include "LLParser.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/AutoUpgrade.h"
+#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
unsigned SlotNo = MDList[i].MDSlot;
- if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
+ if (SlotNo >= NumberedMetadata.size() ||
+ NumberedMetadata[SlotNo] == nullptr)
return Error(MDList[i].Loc, "use of undefined metadata '!" +
Twine(SlotNo) + "'");
Inst->setMetadata(MDList[i].MDKind, NumberedMetadata[SlotNo]);
// references after the function was defined. Resolve those now.
while (!ForwardRefBlockAddresses.empty()) {
// Okay, we are referencing an already-parsed function, resolve them now.
- Function *TheFn = 0;
+ Function *TheFn = nullptr;
const ValID &Fn = ForwardRefBlockAddresses.begin()->first;
if (Fn.Kind == ValID::t_GlobalName)
TheFn = M->getFunction(Fn.StrVal);
else if (Fn.UIntVal < NumberedVals.size())
TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]);
- if (TheFn == 0)
+ if (!TheFn)
return Error(Fn.Loc, "unknown function referenced by blockaddress");
// Resolve all these references.
if (ResolveForwardRefBlockAddresses(TheFn,
ForwardRefBlockAddresses.begin()->second,
- 0))
+ nullptr))
return true;
ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
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 +
TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal));
}
- if (Res == 0)
+ if (!Res)
return Error(Refs[i].first.Loc,
"referenced value is not a basic block");
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;
// The Global variable production with no name can have many different
// optional leading prefixes, the production is:
- // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
- // OptionalAddrSpace OptionalUnNammedAddr
+ // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+ // OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
// ('constant'|'global') ...
case lltok::kw_private: // OptionalLinkage
- case lltok::kw_linker_private: // OptionalLinkage
- case lltok::kw_linker_private_weak: // 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
case lltok::kw_linkonce_odr: // OptionalLinkage
case lltok::kw_appending: // OptionalLinkage
- case lltok::kw_dllexport: // OptionalLinkage
case lltok::kw_common: // OptionalLinkage
- case lltok::kw_dllimport: // OptionalLinkage
case lltok::kw_extern_weak: // OptionalLinkage
- case lltok::kw_external: { // OptionalLinkage
- unsigned Linkage, Visibility;
- if (ParseOptionalLinkage(Linkage) ||
+ 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;
+ bool UnnamedAddr;
+ GlobalVariable::ThreadLocalMode TLM;
+ bool HasLinkage;
+ if (ParseOptionalLinkage(Linkage, HasLinkage) ||
ParseOptionalVisibility(Visibility) ||
- ParseGlobal("", SMLoc(), Linkage, true, Visibility))
- return true;
- break;
- }
- case lltok::kw_default: // OptionalVisibility
- case lltok::kw_hidden: // OptionalVisibility
- case lltok::kw_protected: { // OptionalVisibility
- unsigned Visibility;
- if (ParseOptionalVisibility(Visibility) ||
- ParseGlobal("", SMLoc(), 0, false, Visibility))
+ ParseOptionalDLLStorageClass(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)) return true;
- break;
-
case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break;
}
}
if (TypeID >= NumberedTypes.size())
NumberedTypes.resize(TypeID+1);
- Type *Result = 0;
+ Type *Result = nullptr;
if (ParseStructDefinition(TypeLoc, "",
NumberedTypes[TypeID], Result)) return true;
ParseToken(lltok::kw_type, "expected 'type' after name"))
return true;
- Type *Result = 0;
+ Type *Result = nullptr;
if (ParseStructDefinition(NameLoc, Name,
NamedTypes[Name], Result)) return true;
/// ParseUnnamedGlobal:
/// OptionalVisibility ALIAS ...
-/// OptionalLinkage OptionalVisibility ... -> global variable
+/// OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// ... -> global variable
/// GlobalID '=' OptionalVisibility ALIAS ...
-/// GlobalID '=' OptionalLinkage OptionalVisibility ... -> global variable
+/// GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// ... -> global variable
bool LLParser::ParseUnnamedGlobal() {
unsigned VarID = NumberedVals.size();
std::string Name;
}
bool HasLinkage;
- unsigned Linkage, Visibility;
+ unsigned Linkage, Visibility, DLLStorageClass;
+ GlobalVariable::ThreadLocalMode TLM;
+ bool UnnamedAddr;
if (ParseOptionalLinkage(Linkage, HasLinkage) ||
- ParseOptionalVisibility(Visibility))
+ ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
+ ParseOptionalThreadLocal(TLM) ||
+ parseOptionalUnnamedAddr(UnnamedAddr))
return true;
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
- return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
- return ParseAlias(Name, NameLoc, Visibility);
+ return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+ DLLStorageClass, TLM, UnnamedAddr);
+ return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM,
+ UnnamedAddr);
}
/// ParseNamedGlobal:
/// GlobalVar '=' OptionalVisibility ALIAS ...
-/// GlobalVar '=' OptionalLinkage OptionalVisibility ... -> global variable
+/// GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// ... -> global variable
bool LLParser::ParseNamedGlobal() {
assert(Lex.getKind() == lltok::GlobalVar);
LocTy NameLoc = Lex.getLoc();
Lex.Lex();
bool HasLinkage;
- unsigned Linkage, Visibility;
+ unsigned Linkage, Visibility, DLLStorageClass;
+ GlobalVariable::ThreadLocalMode TLM;
+ bool UnnamedAddr;
if (ParseToken(lltok::equal, "expected '=' in global variable") ||
ParseOptionalLinkage(Linkage, HasLinkage) ||
- ParseOptionalVisibility(Visibility))
+ ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
+ ParseOptionalThreadLocal(TLM) ||
+ parseOptionalUnnamedAddr(UnnamedAddr))
return true;
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
- return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
- return ParseAlias(Name, NameLoc, Visibility);
+ return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+ DLLStorageClass, TLM, UnnamedAddr);
+ return ParseAlias(Name, NameLoc, 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:
bool LLParser::ParseMDString(MDString *&Result) {
std::string Str;
if (ParseStringConstant(Str)) return true;
+ llvm::UpgradeMDStringConstant(Str);
Result = MDString::get(Context, Str);
return false;
}
if (ParseUInt32(SlotNo)) return true;
// Check existing MDNode.
- if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != 0)
+ if (SlotNo < NumberedMetadata.size() && NumberedMetadata[SlotNo] != nullptr)
Result = NumberedMetadata[SlotNo];
else
- Result = 0;
+ Result = nullptr;
return false;
}
if (ParseToken(lltok::exclaim, "Expected '!' here"))
return true;
- MDNode *N = 0;
+ MDNode *N = nullptr;
if (ParseMDNodeID(N)) return true;
NMD->addOperand(N);
} while (EatIfPresent(lltok::comma));
unsigned MetadataID = 0;
LocTy TyLoc;
- Type *Ty = 0;
+ Type *Ty = nullptr;
SmallVector<Value *, 16> Elts;
if (ParseUInt32(MetadataID) ||
ParseToken(lltok::equal, "expected '=' here") ||
ParseType(Ty, TyLoc) ||
ParseToken(lltok::exclaim, "Expected '!' here") ||
ParseToken(lltok::lbrace, "Expected '{' here") ||
- ParseMDNodeVector(Elts, NULL) ||
+ ParseMDNodeVector(Elts, nullptr) ||
ParseToken(lltok::rbrace, "expected end of metadata node"))
return true;
if (MetadataID >= NumberedMetadata.size())
NumberedMetadata.resize(MetadataID+1);
- if (NumberedMetadata[MetadataID] != 0)
+ if (NumberedMetadata[MetadataID] != nullptr)
return TokError("Metadata id is already used");
NumberedMetadata[MetadataID] = Init;
}
return false;
}
+static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
+ return !GlobalValue::isLocalLinkage((GlobalValue::LinkageTypes)L) ||
+ (GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility;
+}
+
/// ParseAlias:
-/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
+/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalUnNammedAddr 'alias'
+/// OptionalLinkage Aliasee
+///
/// Aliasee
/// ::= TypeAndValue
-/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
-/// ::= 'getelementptr' 'inbounds'? '(' ... ')'
///
-/// Everything through visibility has already been parsed.
+/// Everything through OptionalUnNammedAddr has already been parsed.
///
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
- unsigned Visibility) {
+ unsigned Visibility, unsigned DLLStorageClass,
+ GlobalVariable::ThreadLocalMode TLM,
+ bool UnnamedAddr) {
assert(Lex.getKind() == lltok::kw_alias);
Lex.Lex();
LocTy LinkageLoc = Lex.getLoc();
if(!GlobalAlias::isValidLinkage(Linkage))
return Error(LinkageLoc, "invalid linkage type for alias");
+ if (!isValidVisibilityForLinkage(Visibility, L))
+ return Error(LinkageLoc,
+ "symbol with local linkage must have default visibility");
+
Constant *Aliasee;
LocTy AliaseeLoc = Lex.getLoc();
if (Lex.getKind() != lltok::kw_bitcast &&
- Lex.getKind() != lltok::kw_getelementptr) {
- if (ParseGlobalTypeAndValue(Aliasee)) return true;
+ Lex.getKind() != lltok::kw_getelementptr &&
+ Lex.getKind() != lltok::kw_addrspacecast &&
+ Lex.getKind() != lltok::kw_inttoptr) {
+ if (ParseGlobalTypeAndValue(Aliasee))
+ return true;
} else {
// The bitcast dest type is not present, it is implied by the dest type.
ValID ID;
- if (ParseValID(ID)) return true;
+ if (ParseValID(ID))
+ return true;
if (ID.Kind != ValID::t_Constant)
return Error(AliaseeLoc, "invalid aliasee");
Aliasee = ID.ConstantVal;
}
- if (!Aliasee->getType()->isPointerTy())
- return Error(AliaseeLoc, "alias must have pointer type");
+ 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.
- GlobalAlias* GA = new GlobalAlias(Aliasee->getType(),
- (GlobalValue::LinkageTypes)Linkage, Name,
- Aliasee);
+ std::unique_ptr<GlobalAlias> GA(
+ 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.
- Val->replaceAllUsesWith(GA);
+ Val->replaceAllUsesWith(GA.get());
Val->eraseFromParent();
ForwardRefVals.erase(I);
}
// Insert into the module, we know its name won't collide now.
- M->getAliasList().push_back(GA);
+ M->getAliasList().push_back(GA.get());
assert(GA->getName() == Name && "Should not be a name conflict!");
+ // The module owns this now
+ GA.release();
+
return false;
}
/// ParseGlobal
-/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal
-/// OptionalAddrSpace OptionalUnNammedAddr
+/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace
/// OptionalExternallyInitialized GlobalType Type Const
-/// ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
-/// OptionalAddrSpace OptionalUnNammedAddr
+/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalUnNammedAddr OptionalAddrSpace
/// OptionalExternallyInitialized GlobalType Type Const
///
-/// Everything through visibility has been parsed already.
+/// 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 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 = 0;
- if (ParseOptionalThreadLocal(TLM) ||
- ParseOptionalAddrSpace(AddrSpace) ||
- ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
- &UnnamedAddrLoc) ||
+ Type *Ty = nullptr;
+ if (ParseOptionalAddrSpace(AddrSpace) ||
ParseOptionalToken(lltok::kw_externally_initialized,
IsExternallyInitialized,
&IsExternallyInitializedLoc) ||
// If the linkage is specified and is external, then no initializer is
// present.
- Constant *Init = 0;
- if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage &&
- Linkage != GlobalValue::ExternalWeakLinkage &&
+ Constant *Init = nullptr;
+ if (!HasLinkage || (Linkage != GlobalValue::ExternalWeakLinkage &&
Linkage != GlobalValue::ExternalLinkage)) {
if (ParseGlobalValue(Ty, Init))
return true;
if (Ty->isFunctionTy() || Ty->isLabelTy())
return Error(TyLoc, "invalid type for global variable");
- GlobalVariable *GV = 0;
+ GlobalVariable *GV = nullptr;
// See if the global was forward referenced, if so, use the global.
if (!Name.empty()) {
}
}
- if (GV == 0) {
- GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, 0,
- Name, 0, GlobalVariable::NotThreadLocal,
+ if (!GV) {
+ GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr,
+ Name, nullptr, GlobalVariable::NotThreadLocal,
AddrSpace);
} else {
if (GV->getType()->getElementType() != Ty)
GV->setConstant(IsConstant);
GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+ GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
GV->setExternallyInitialized(IsExternallyInitialized);
GV->setThreadLocalMode(TLM);
GV->setUnnamedAddr(UnnamedAddr);
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!");
}
}
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 |=
GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty,
LocTy Loc) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
- if (PTy == 0) {
+ if (!PTy) {
Error(Loc, "global variable reference must have pointer type");
- return 0;
+ return nullptr;
}
// Look this name up in the normal function symbol table.
// If this is a forward reference for the value, see if we already created a
// forward ref record.
- if (Val == 0) {
+ if (!Val) {
std::map<std::string, std::pair<GlobalValue*, LocTy> >::iterator
I = ForwardRefVals.find(Name);
if (I != ForwardRefVals.end())
if (Val->getType() == Ty) return Val;
Error(Loc, "'@" + Name + "' defined with type '" +
getTypeString(Val->getType()) + "'");
- return 0;
+ return nullptr;
}
// Otherwise, create a new forward reference for this value and remember it.
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalWeakLinkage, 0, Name,
- 0, GlobalVariable::NotThreadLocal,
+ GlobalValue::ExternalWeakLinkage, nullptr, Name,
+ nullptr, GlobalVariable::NotThreadLocal,
PTy->getAddressSpace());
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) {
PointerType *PTy = dyn_cast<PointerType>(Ty);
- if (PTy == 0) {
+ if (!PTy) {
Error(Loc, "global variable reference must have pointer type");
- return 0;
+ return nullptr;
}
- GlobalValue *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0;
+ GlobalValue *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;
// If this is a forward reference for the value, see if we already created a
// forward ref record.
- if (Val == 0) {
+ if (!Val) {
std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
I = ForwardRefValIDs.find(ID);
if (I != ForwardRefValIDs.end())
if (Val->getType() == Ty) return Val;
Error(Loc, "'@" + Twine(ID) + "' defined with type '" +
getTypeString(Val->getType()) + "'");
- return 0;
+ return nullptr;
}
// Otherwise, create a new forward reference for this value and remember it.
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M);
else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalWeakLinkage, 0, "");
+ GlobalValue::ExternalWeakLinkage, nullptr, "");
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
}
+//===----------------------------------------------------------------------===//
+// 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.
//===----------------------------------------------------------------------===//
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:
/// ParseOptionalLinkage
/// ::= /*empty*/
/// ::= 'private'
-/// ::= 'linker_private'
-/// ::= 'linker_private_weak'
/// ::= 'internal'
/// ::= 'weak'
/// ::= 'weak_odr'
/// ::= 'linkonce_odr'
/// ::= 'available_externally'
/// ::= 'appending'
-/// ::= 'dllexport'
/// ::= 'common'
-/// ::= 'dllimport'
/// ::= 'extern_weak'
/// ::= 'external'
+///
+/// Deprecated Values:
+/// ::= 'linker_private'
+/// ::= 'linker_private_weak'
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
HasLinkage = false;
switch (Lex.getKind()) {
default: Res=GlobalValue::ExternalLinkage; return false;
case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break;
- case lltok::kw_linker_private: Res = GlobalValue::LinkerPrivateLinkage; break;
- case lltok::kw_linker_private_weak:
- Res = GlobalValue::LinkerPrivateWeakLinkage;
- break;
case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break;
case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break;
case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break;
Res = GlobalValue::AvailableExternallyLinkage;
break;
case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break;
- case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break;
case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
- case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; 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;
return false;
}
+/// ParseOptionalDLLStorageClass
+/// ::= /*empty*/
+/// ::= 'dllimport'
+/// ::= 'dllexport'
+///
+bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) {
+ switch (Lex.getKind()) {
+ default: Res = GlobalValue::DefaultStorageClass; return false;
+ case lltok::kw_dllimport: Res = GlobalValue::DLLImportStorageClass; break;
+ case lltok::kw_dllexport: Res = GlobalValue::DLLExportStorageClass; break;
+ }
+ Lex.Lex();
+ return false;
+}
+
/// ParseOptionalCallingConv
/// ::= /*empty*/
/// ::= 'ccc'
/// ::= 'x86_64_win64cc'
/// ::= 'webkit_jscc'
/// ::= 'anyregcc'
+/// ::= 'preserve_mostcc'
+/// ::= 'preserve_allcc'
/// ::= 'cc' UINT
///
bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
case lltok::kw_x86_64_win64cc: CC = CallingConv::X86_64_Win64; break;
case lltok::kw_webkit_jscc: CC = CallingConv::WebKit_JS; break;
case lltok::kw_anyregcc: CC = CallingConv::AnyReg; break;
+ case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break;
+ case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break;
case lltok::kw_cc: {
unsigned ArbitraryCC;
Lex.Lex();
Scope = CrossThread;
if (EatIfPresent(lltok::kw_singlethread))
Scope = SingleThread;
+
+ return ParseOrdering(Ordering);
+}
+
+/// ParseOrdering
+/// ::= AtomicOrdering
+///
+/// This sets Ordering to the parsed value.
+bool LLParser::ParseOrdering(AtomicOrdering &Ordering) {
switch (Lex.getKind()) {
default: return TokError("Expected ordering on atomic instruction");
case lltok::kw_unordered: Ordering = Unordered; break;
// If the type hasn't been defined yet, create a forward definition and
// remember where that forward def'n was seen (in case it never is defined).
- if (Entry.first == 0) {
+ if (!Entry.first) {
Entry.first = StructType::create(Context, Lex.getStrVal());
Entry.second = Lex.getLoc();
}
// If the type hasn't been defined yet, create a forward definition and
// remember where that forward def'n was seen (in case it never is defined).
- if (Entry.first == 0) {
+ if (!Entry.first) {
Entry.first = StructType::create(Context);
Entry.second = Lex.getLoc();
}
// Parse the argument.
LocTy ArgLoc;
- Type *ArgTy = 0;
+ Type *ArgTy = nullptr;
AttrBuilder ArgAttrs;
Value *V;
if (ParseType(ArgTy, ArgLoc))
Lex.Lex();
} else {
LocTy TypeLoc = Lex.getLoc();
- Type *ArgTy = 0;
+ Type *ArgTy = nullptr;
AttrBuilder Attrs;
std::string Name;
Entry.second = SMLoc();
// If this type number has never been uttered, create it.
- if (Entry.first == 0)
+ if (!Entry.first)
Entry.first = StructType::create(Context, Name);
ResultTy = Entry.first;
return false;
if (Entry.first)
return Error(TypeLoc, "forward references to non-struct type");
- ResultTy = 0;
+ ResultTy = nullptr;
if (isPacked)
return ParseArrayVectorType(ResultTy, true);
return ParseType(ResultTy);
Entry.second = SMLoc();
// If this type number has never been uttered, create it.
- if (Entry.first == 0)
+ if (!Entry.first)
Entry.first = StructType::create(Context, Name);
StructType *STy = cast<StructType>(Entry.first);
return false;
LocTy EltTyLoc = Lex.getLoc();
- Type *Ty = 0;
+ Type *Ty = nullptr;
if (ParseType(Ty)) return true;
Body.push_back(Ty);
return true;
LocTy TypeLoc = Lex.getLoc();
- Type *EltTy = 0;
+ Type *EltTy = nullptr;
if (ParseType(EltTy)) return true;
if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
I->second.first->replaceAllUsesWith(
UndefValue::get(I->second.first->getType()));
delete I->second.first;
- I->second.first = 0;
+ I->second.first = nullptr;
}
for (std::map<unsigned, std::pair<Value*, LocTy> >::iterator
I->second.first->replaceAllUsesWith(
UndefValue::get(I->second.first->getType()));
delete I->second.first;
- I->second.first = 0;
+ I->second.first = nullptr;
}
}
// If this is a forward reference for the value, see if we already created a
// forward ref record.
- if (Val == 0) {
+ if (!Val) {
std::map<std::string, std::pair<Value*, LocTy> >::iterator
I = ForwardRefVals.find(Name);
if (I != ForwardRefVals.end())
else
P.Error(Loc, "'%" + Name + "' defined with type '" +
getTypeString(Val->getType()) + "'");
- return 0;
+ return nullptr;
}
// Don't make placeholders with invalid type.
if (!Ty->isFirstClassType() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
- return 0;
+ return nullptr;
}
// Otherwise, create a new forward reference for this value and remember it.
Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
LocTy Loc) {
// Look this name up in the normal function symbol table.
- Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0;
+ Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;
// If this is a forward reference for the value, see if we already created a
// forward ref record.
- if (Val == 0) {
+ if (!Val) {
std::map<unsigned, std::pair<Value*, LocTy> >::iterator
I = ForwardRefValIDs.find(ID);
if (I != ForwardRefValIDs.end())
else
P.Error(Loc, "'%" + Twine(ID) + "' defined with type '" +
getTypeString(Val->getType()) + "'");
- return 0;
+ return nullptr;
}
if (!Ty->isFirstClassType() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
- return 0;
+ return nullptr;
}
// Otherwise, create a new forward reference for this value and remember it.
BB = GetBB(NumberedVals.size(), Loc);
else
BB = GetBB(Name, Loc);
- if (BB == 0) return 0; // Already diagnosed error.
+ if (!BB) return nullptr; // Already diagnosed error.
// Move the block to the end of the function. Forward ref'd blocks are
// inserted wherever they happen to be referenced.
// Make a global variable as a placeholder for this reference.
GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context),
false, GlobalValue::InternalLinkage,
- 0, "");
+ nullptr, "");
ForwardRefBlockAddresses[Fn].push_back(std::make_pair(Label, FwdRef));
ID.ConstantVal = FwdRef;
ID.Kind = ValID::t_Constant;
case lltok::kw_inttoptr:
case lltok::kw_ptrtoint: {
unsigned Opc = Lex.getUIntVal();
- Type *DestTy = 0;
+ Type *DestTy = nullptr;
Constant *SrcVal;
Lex.Lex();
if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
/// ParseGlobalValue - Parse a global value with the specified type.
bool LLParser::ParseGlobalValue(Type *Ty, Constant *&C) {
- C = 0;
+ C = nullptr;
ValID ID;
- Value *V = NULL;
+ Value *V = nullptr;
bool Parsed = ParseValID(ID) ||
- ConvertValIDToValue(Ty, ID, V, NULL);
+ ConvertValIDToValue(Ty, ID, V, nullptr);
if (V && !(C = dyn_cast<Constant>(V)))
return Error(ID.Loc, "global values must be constants");
return Parsed;
}
bool LLParser::ParseGlobalTypeAndValue(Constant *&V) {
- Type *Ty = 0;
+ Type *Ty = nullptr;
return ParseType(Ty) ||
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)*
case ValID::t_LocalID:
if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc);
- return (V == 0);
+ return V == nullptr;
case ValID::t_LocalName:
if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
- return (V == 0);
+ return V == nullptr;
case ValID::t_InlineAsm: {
PointerType *PTy = dyn_cast<PointerType>(Ty);
FunctionType *FTy =
- PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
+ PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : nullptr;
if (!FTy || !InlineAsm::Verify(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,
return false;
case ValID::t_GlobalName:
V = GetGlobalVal(ID.StrVal, Ty, ID.Loc);
- return V == 0;
+ return V == nullptr;
case ValID::t_GlobalID:
V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc);
- return V == 0;
+ return V == nullptr;
case ValID::t_APSInt:
if (!Ty->isIntegerTy())
return Error(ID.Loc, "integer constant must have integer type");
}
bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
- V = 0;
+ V = nullptr;
ValID ID;
return ParseValID(ID, PFS) ||
ConvertValIDToValue(Ty, ID, V, PFS);
}
bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) {
- Type *Ty = 0;
+ Type *Ty = nullptr;
return ParseType(Ty) ||
ParseValue(Ty, V, PFS);
}
unsigned Linkage;
unsigned Visibility;
+ unsigned DLLStorageClass;
AttrBuilder RetAttrs;
CallingConv::ID CC;
- Type *RetType = 0;
+ Type *RetType = nullptr;
LocTy RetTypeLoc = Lex.getLoc();
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
ParseOptionalCallingConv(CC) ||
ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
switch ((GlobalValue::LinkageTypes)Linkage) {
case GlobalValue::ExternalLinkage:
break; // always ok.
- case GlobalValue::DLLImportLinkage:
case GlobalValue::ExternalWeakLinkage:
if (isDefine)
return Error(LinkageLoc, "invalid linkage for function definition");
break;
case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::LinkerPrivateWeakLinkage:
case GlobalValue::InternalLinkage:
case GlobalValue::AvailableExternallyLinkage:
case GlobalValue::LinkOnceAnyLinkage:
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
- case GlobalValue::DLLExportLinkage:
if (!isDefine)
return Error(LinkageLoc, "invalid linkage for function declaration");
break;
return Error(LinkageLoc, "invalid function linkage type");
}
+ if (!isValidVisibilityForLinkage(Visibility, Linkage))
+ return Error(LinkageLoc,
+ "symbol with local linkage must have default visibility");
+
if (!FunctionType::isValidReturnType(RetType))
return Error(RetTypeLoc, "invalid function return type");
std::string GC;
bool UnnamedAddr;
LocTy UnnamedAddrLoc;
- Constant *Prefix = 0;
+ Constant *Prefix = nullptr;
+ Comdat *C;
if (ParseArgumentList(ArgList, isVarArg) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
BuiltinLoc) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
+ parseOptionalComdat(C) ||
ParseOptionalAlignment(Alignment) ||
(EatIfPresent(lltok::kw_gc) &&
ParseStringConstant(GC)) ||
FunctionType::get(RetType, ParamTypeList, isVarArg);
PointerType *PFT = PointerType::getUnqual(FT);
- Fn = 0;
+ Fn = nullptr;
if (!FunctionName.empty()) {
// If this was a definition of a forward reference, remove the definition
// from the forward reference table and fill in the forward ref.
}
}
- if (Fn == 0)
+ if (!Fn)
Fn = Function::Create(FT, GlobalValue::ExternalLinkage, FunctionName, M);
else // Move the forward-reference to the correct spot in the module.
M->getFunctionList().splice(M->end(), M->getFunctionList(), Fn);
Fn->setLinkage((GlobalValue::LinkageTypes)Linkage);
Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+ Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
Fn->setCallingConv(CC);
Fn->setAttributes(PAL);
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;
}
BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
- if (BB == 0) return true;
+ if (!BB) return true;
std::string NameStr;
case lltok::kw_shufflevector: return ParseShuffleVector(Inst, PFS);
case lltok::kw_phi: return ParsePHI(Inst, PFS);
case lltok::kw_landingpad: return ParseLandingPad(Inst, PFS);
- case lltok::kw_call: return ParseCall(Inst, PFS, false);
- case lltok::kw_tail: return ParseCall(Inst, PFS, true);
+ // Call.
+ case lltok::kw_call: return ParseCall(Inst, PFS, CallInst::TCK_None);
+ case lltok::kw_tail: return ParseCall(Inst, PFS, CallInst::TCK_Tail);
+ case lltok::kw_musttail: return ParseCall(Inst, PFS, CallInst::TCK_MustTail);
// Memory.
case lltok::kw_alloca: return ParseAlloc(Inst, PFS);
case lltok::kw_load: return ParseLoad(Inst, PFS);
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
PerFunctionState &PFS) {
SMLoc TypeLoc = Lex.getLoc();
- Type *Ty = 0;
+ Type *Ty = nullptr;
if (ParseType(Ty, true /*void allowed*/)) return true;
Type *ResType = PFS.getFunction().getReturnType();
std::vector<unsigned> FwdRefAttrGrps;
LocTy NoBuiltinLoc;
CallingConv::ID CC;
- Type *RetType = 0;
+ Type *RetType = nullptr;
LocTy RetTypeLoc;
ValID CalleeID;
SmallVector<ParamInfo, 16> ArgList;
// If RetType is a non-function pointer type, then this is the short syntax
// for the call, which means that RetType is just the return type. Infer the
// rest of the function argument types from the arguments that are present.
- PointerType *PFTy = 0;
- FunctionType *Ty = 0;
+ PointerType *PFTy = nullptr;
+ FunctionType *Ty = nullptr;
if (!(PFTy = dyn_cast<PointerType>(RetType)) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
FunctionType::param_iterator I = Ty->param_begin();
FunctionType::param_iterator E = Ty->param_end();
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
- Type *ExpectedTy = 0;
+ Type *ExpectedTy = nullptr;
if (I != E) {
ExpectedTy = *I++;
} else if (!Ty->isVarArg()) {
unsigned Opc) {
LocTy Loc;
Value *Op;
- Type *DestTy = 0;
+ Type *DestTy = nullptr;
if (ParseTypeAndValue(Op, Loc, PFS) ||
ParseToken(lltok::kw_to, "expected 'to' after cast value") ||
ParseType(DestTy))
/// ::= 'va_arg' TypeAndValue ',' Type
bool LLParser::ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS) {
Value *Op;
- Type *EltTy = 0;
+ Type *EltTy = nullptr;
LocTy TypeLoc;
if (ParseTypeAndValue(Op, PFS) ||
ParseToken(lltok::comma, "expected ',' after vaarg operand") ||
/// ParsePHI
/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')*
int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
- Type *Ty = 0; LocTy TypeLoc;
+ Type *Ty = nullptr; LocTy TypeLoc;
Value *Op0, *Op1;
if (ParseType(Ty, TypeLoc) ||
/// ::= 'filter'
/// ::= 'filter' TypeAndValue ( ',' TypeAndValue )*
bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
- Type *Ty = 0; LocTy TyLoc;
+ Type *Ty = nullptr; LocTy TyLoc;
Value *PersFn; LocTy PersFnLoc;
if (ParseType(Ty, TyLoc) ||
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;
}
/// ParseCall
-/// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value
+/// ::= 'call' OptionalCallingConv OptionalAttrs Type Value
+/// ParameterList OptionalAttrs
+/// ::= 'tail' 'call' OptionalCallingConv OptionalAttrs Type Value
+/// ParameterList OptionalAttrs
+/// ::= 'musttail' 'call' OptionalCallingConv OptionalAttrs Type Value
/// ParameterList OptionalAttrs
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
- bool isTail) {
+ CallInst::TailCallKind TCK) {
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
LocTy BuiltinLoc;
CallingConv::ID CC;
- Type *RetType = 0;
+ Type *RetType = nullptr;
LocTy RetTypeLoc;
ValID CalleeID;
SmallVector<ParamInfo, 16> ArgList;
LocTy CallLoc = Lex.getLoc();
- if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
+ if ((TCK != CallInst::TCK_None &&
+ ParseToken(lltok::kw_call, "expected 'tail call'")) ||
ParseOptionalCallingConv(CC) ||
ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
// If RetType is a non-function pointer type, then this is the short syntax
// for the call, which means that RetType is just the return type. Infer the
// rest of the function argument types from the arguments that are present.
- PointerType *PFTy = 0;
- FunctionType *Ty = 0;
+ PointerType *PFTy = nullptr;
+ FunctionType *Ty = nullptr;
if (!(PFTy = dyn_cast<PointerType>(RetType)) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
FunctionType::param_iterator I = Ty->param_begin();
FunctionType::param_iterator E = Ty->param_end();
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
- Type *ExpectedTy = 0;
+ Type *ExpectedTy = nullptr;
if (I != E) {
ExpectedTy = *I++;
} else if (!Ty->isVarArg()) {
AttributeSet PAL = AttributeSet::get(Context, Attrs);
CallInst *CI = CallInst::Create(Callee, Args);
- CI->setTailCall(isTail);
+ CI->setTailCallKind(TCK);
CI->setCallingConv(CC);
CI->setAttributes(PAL);
ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
//===----------------------------------------------------------------------===//
/// ParseAlloc
-/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
+/// ::= 'alloca' 'inalloca'? Type (',' TypeAndValue)? (',' 'align' i32)?
int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
- Value *Size = 0;
+ Value *Size = nullptr;
LocTy SizeLoc;
unsigned Alignment = 0;
- Type *Ty = 0;
+ Type *Ty = nullptr;
+
+ bool IsInAlloca = EatIfPresent(lltok::kw_inalloca);
+
if (ParseType(Ty)) return true;
bool AteExtraComma = false;
if (Size && !Size->getType()->isIntegerTy())
return Error(SizeLoc, "element count must have integer type");
- Inst = new AllocaInst(Ty, Size, Alignment);
+ AllocaInst *AI = new AllocaInst(Ty, Size, Alignment);
+ AI->setUsedWithInAlloca(IsInAlloca);
+ Inst = AI;
return AteExtraComma ? InstExtraComma : InstNormal;
}
}
/// ParseCmpXchg
-/// ::= 'cmpxchg' 'volatile'? TypeAndValue ',' TypeAndValue ',' TypeAndValue
-/// 'singlethread'? 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 Ordering = NotAtomic;
+ AtomicOrdering SuccessOrdering = NotAtomic;
+ 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;
ParseTypeAndValue(Cmp, CmpLoc, PFS) ||
ParseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") ||
ParseTypeAndValue(New, NewLoc, PFS) ||
- ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering))
+ ParseScopeAndOrdering(true /*Always atomic*/, Scope, SuccessOrdering) ||
+ ParseOrdering(FailureOrdering))
return true;
- if (Ordering == Unordered)
+ if (SuccessOrdering == Unordered || FailureOrdering == Unordered)
return TokError("cmpxchg cannot be unordered");
+ if (SuccessOrdering < FailureOrdering)
+ return TokError("cmpxchg must be at least as ordered on success as failure");
+ if (FailureOrdering == Release || FailureOrdering == AcquireRelease)
+ return TokError("cmpxchg failure ordering cannot include release semantics");
if (!Ptr->getType()->isPointerTy())
return Error(PtrLoc, "cmpxchg operand must be a pointer");
if (cast<PointerType>(Ptr->getType())->getElementType() != Cmp->getType())
return Error(NewLoc, "cmpxchg operand must be power-of-two byte-sized"
" integer");
- AtomicCmpXchgInst *CXI =
- new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, Scope);
+ AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst(
+ Ptr, Cmp, New, SuccessOrdering, FailureOrdering, Scope);
CXI->setVolatile(isVolatile);
+ CXI->setWeak(isWeak);
Inst = CXI;
return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseGetElementPtr
/// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)*
int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
- Value *Ptr = 0;
- Value *Val = 0;
+ Value *Ptr = nullptr;
+ Value *Val = nullptr;
LocTy Loc, EltLoc;
bool InBounds = EatIfPresent(lltok::kw_inbounds);
do {
// Null is a special case since it is typeless.
if (EatIfPresent(lltok::kw_null)) {
- Elts.push_back(0);
+ Elts.push_back(nullptr);
continue;
}
- Value *V = 0;
+ Value *V = nullptr;
if (ParseTypeAndValue(V, PFS)) return true;
Elts.push_back(V);
} while (EatIfPresent(lltok::comma));