//===----------------------------------------------------------------------===//
#include "LLParser.h"
-#include "llvm/AutoUpgrade.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/InlineAsm.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Operator.h"
-#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/AutoUpgrade.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
I != E; ++I) {
Instruction *Inst = I->first;
const std::vector<MDRef> &MDList = I->second;
-
+
for (unsigned i = 0, e = MDList.size(); i != e; ++i) {
unsigned SlotNo = MDList[i].MDSlot;
-
+
if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0)
return Error(MDList[i].Loc, "use of undefined metadata '!" +
Twine(SlotNo) + "'");
}
ForwardRefInstMetadata.clear();
}
-
-
+
+ for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++)
+ UpgradeInstWithTBAATag(InstsWithTBAATag[I]);
+
+ // Handle any function attribute group forward references.
+ for (std::map<Value*, std::vector<unsigned> >::iterator
+ I = ForwardRefAttrGroups.begin(), E = ForwardRefAttrGroups.end();
+ I != E; ++I) {
+ Value *V = I->first;
+ std::vector<unsigned> &Vec = I->second;
+ AttrBuilder B;
+
+ for (std::vector<unsigned>::iterator VI = Vec.begin(), VE = Vec.end();
+ VI != VE; ++VI)
+ B.merge(NumberedAttrBuilders[*VI]);
+
+ 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());
+
+ FnAttrs.merge(B);
+
+ // If the alignment was parsed as an attribute, move to the alignment
+ // field.
+ if (FnAttrs.hasAlignmentAttr()) {
+ Fn->setAlignment(FnAttrs.getAlignment());
+ FnAttrs.removeAttribute(Attribute::Alignment);
+ }
+
+ AS = AS.addAttributes(Context, AttributeSet::FunctionIndex,
+ AttributeSet::get(Context,
+ AttributeSet::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());
+ FnAttrs.merge(B);
+ AS = AS.addAttributes(Context, AttributeSet::FunctionIndex,
+ AttributeSet::get(Context,
+ AttributeSet::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());
+ FnAttrs.merge(B);
+ AS = AS.addAttributes(Context, AttributeSet::FunctionIndex,
+ AttributeSet::get(Context,
+ AttributeSet::FunctionIndex,
+ FnAttrs));
+ II->setAttributes(AS);
+ } else {
+ llvm_unreachable("invalid object with forward attribute group reference");
+ }
+ }
+
// If there are entries in ForwardRefBlockAddresses at this point, they are
// references after the function was defined. Resolve those now.
while (!ForwardRefBlockAddresses.empty()) {
TheFn = M->getFunction(Fn.StrVal);
else if (Fn.UIntVal < NumberedVals.size())
TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]);
-
+
if (TheFn == 0)
return Error(Fn.Loc, "unknown function referenced by blockaddress");
-
+
// Resolve all these references.
- if (ResolveForwardRefBlockAddresses(TheFn,
+ if (ResolveForwardRefBlockAddresses(TheFn,
ForwardRefBlockAddresses.begin()->second,
0))
return true;
-
+
ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
}
-
+
for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
if (NumberedTypes[i].second.isValid())
return Error(NumberedTypes[i].second,
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
+ UpgradeDebugInfo(*M);
+
return false;
}
-bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
+bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
std::vector<std::pair<ValID, GlobalValue*> > &Refs,
PerFunctionState *PFS) {
// Loop over all the references, resolving them.
Res = dyn_cast_or_null<BasicBlock>(
TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal));
}
-
+
if (Res == 0)
return Error(Refs[i].first.Loc,
"referenced value is not a basic block");
-
+
// Get the BlockAddress for this and update references to use it.
BlockAddress *BA = BlockAddress::get(TheFn, Res);
Refs[i].second->replaceAllUsesWith(BA);
case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break;
case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break;
case lltok::exclaim: if (ParseStandaloneMetadata()) return true; break;
- case lltok::MetadataVar: if (ParseNamedMetadata()) 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_linker_private_weak_def_auto: // OptionalLinkage
case lltok::kw_internal: // 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;
+ unsigned Linkage, Visibility, DLLStorageClass;
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
- ParseGlobal("", SMLoc(), Linkage, true, 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;
+ unsigned Visibility, DLLStorageClass;
if (ParseOptionalVisibility(Visibility) ||
- ParseGlobal("", SMLoc(), 0, false, Visibility))
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
+ ParseGlobal("", SMLoc(), 0, false, Visibility, DLLStorageClass))
return true;
break;
}
case lltok::kw_addrspace: // OptionalAddrSpace
case lltok::kw_constant: // GlobalType
case lltok::kw_global: // GlobalType
- if (ParseGlobal("", SMLoc(), 0, false, 0)) return true;
+ if (ParseGlobal("", SMLoc(), 0, false, 0, 0)) return true;
break;
+
+ case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break;
}
}
}
/// toplevelentity
/// ::= 'deplibs' '=' '[' ']'
/// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']'
+/// FIXME: Remove in 4.0. Currently parse, but ignore.
bool LLParser::ParseDepLibs() {
assert(Lex.getKind() == lltok::kw_deplibs);
Lex.Lex();
if (EatIfPresent(lltok::rsquare))
return false;
- std::string Str;
- if (ParseStringConstant(Str)) return true;
- M->addLibrary(Str);
-
- while (EatIfPresent(lltok::comma)) {
+ do {
+ std::string Str;
if (ParseStringConstant(Str)) return true;
- M->addLibrary(Str);
- }
+ } while (EatIfPresent(lltok::comma));
return ParseToken(lltok::rsquare, "expected ']' at end of list");
}
if (TypeID >= NumberedTypes.size())
NumberedTypes.resize(TypeID+1);
-
+
Type *Result = 0;
if (ParseStructDefinition(TypeLoc, "",
NumberedTypes[TypeID], Result)) return true;
-
+
if (!isa<StructType>(Result)) {
std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
if (Entry.first)
if (ParseToken(lltok::equal, "expected '=' after name") ||
ParseToken(lltok::kw_type, "expected 'type' after name"))
return true;
-
+
Type *Result = 0;
if (ParseStructDefinition(NameLoc, Name,
NamedTypes[Name], Result)) return true;
-
+
if (!isa<StructType>(Result)) {
std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
if (Entry.first)
Entry.first = Result;
Entry.second = SMLoc();
}
-
+
return false;
}
/// 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;
if (ParseOptionalLinkage(Linkage, HasLinkage) ||
- ParseOptionalVisibility(Visibility))
+ ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass))
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);
+ return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
}
/// 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;
if (ParseToken(lltok::equal, "expected '=' in global variable") ||
ParseOptionalLinkage(Linkage, HasLinkage) ||
- ParseOptionalVisibility(Visibility))
+ ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass))
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);
+ return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
}
// MDString:
if (Result) return false;
// Otherwise, create MDNode forward reference.
- MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef<Value*>());
+ MDNode *FwdNode = MDNode::getTemporary(Context, None);
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
-
+
if (NumberedMetadata.size() <= MID)
NumberedMetadata.resize(MID+1);
NumberedMetadata[MID] = FwdNode;
do {
if (ParseToken(lltok::exclaim, "Expected '!' here"))
return true;
-
+
MDNode *N = 0;
if (ParseMDNodeID(N)) return true;
NMD->addOperand(N);
return true;
MDNode *Init = MDNode::get(Context, Elts);
-
+
// See if this was forward referenced, if so, handle it.
std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator
FI = ForwardRefMDNodes.find(MetadataID);
Temp->replaceAllUsesWith(Init);
MDNode::deleteTemporary(Temp);
ForwardRefMDNodes.erase(FI);
-
+
assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
} else {
if (MetadataID >= NumberedMetadata.size())
}
/// ParseAlias:
-/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
+/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias'
+/// OptionalLinkage Aliasee
/// Aliasee
/// ::= TypeAndValue
/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
/// ::= 'getelementptr' 'inbounds'? '(' ... ')'
///
-/// Everything through visibility has already been parsed.
+/// Everything through DLL storage class has already been parsed.
///
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
- unsigned Visibility) {
+ unsigned Visibility, unsigned DLLStorageClass) {
assert(Lex.getKind() == lltok::kw_alias);
Lex.Lex();
- unsigned Linkage;
LocTy LinkageLoc = Lex.getLoc();
- if (ParseOptionalLinkage(Linkage))
+ unsigned L;
+ if (ParseOptionalLinkage(L))
return true;
- if (Linkage != GlobalValue::ExternalLinkage &&
- Linkage != GlobalValue::WeakAnyLinkage &&
- Linkage != GlobalValue::WeakODRLinkage &&
- Linkage != GlobalValue::InternalLinkage &&
- Linkage != GlobalValue::PrivateLinkage &&
- Linkage != GlobalValue::LinkerPrivateLinkage &&
- Linkage != GlobalValue::LinkerPrivateWeakLinkage &&
- Linkage != GlobalValue::LinkerPrivateWeakDefAutoLinkage)
+ GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;
+
+ if(!GlobalAlias::isValidLinkage(Linkage))
return Error(LinkageLoc, "invalid linkage type for alias");
Constant *Aliasee;
(GlobalValue::LinkageTypes)Linkage, Name,
Aliasee);
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+ GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
// See if this value already exists in the symbol table. If so, it is either
// a redefinition or a definition of a forward reference.
}
/// ParseGlobal
-/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal
-/// OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const
-/// ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
-/// OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const
+/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
+/// OptionalExternallyInitialized GlobalType Type Const
+/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
+/// OptionalExternallyInitialized GlobalType Type Const
///
/// Everything through visibility has been parsed already.
///
bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
unsigned Linkage, bool HasLinkage,
- unsigned Visibility) {
+ unsigned Visibility, unsigned DLLStorageClass) {
unsigned AddrSpace;
- bool ThreadLocal, IsConstant, UnnamedAddr;
+ bool IsConstant, UnnamedAddr, IsExternallyInitialized;
+ GlobalVariable::ThreadLocalMode TLM;
LocTy UnnamedAddrLoc;
+ LocTy IsExternallyInitializedLoc;
LocTy TyLoc;
Type *Ty = 0;
- if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) ||
+ if (ParseOptionalThreadLocal(TLM) ||
ParseOptionalAddrSpace(AddrSpace) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
&UnnamedAddrLoc) ||
+ ParseOptionalToken(lltok::kw_externally_initialized,
+ IsExternallyInitialized,
+ &IsExternallyInitializedLoc) ||
ParseGlobalType(IsConstant) ||
ParseType(Ty, TyLoc))
return true;
// If the linkage is specified and is external, then no initializer is
// present.
Constant *Init = 0;
- if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage &&
- Linkage != GlobalValue::ExternalWeakLinkage &&
+ if (!HasLinkage || (Linkage != GlobalValue::ExternalWeakLinkage &&
Linkage != GlobalValue::ExternalLinkage)) {
if (ParseGlobalValue(Ty, Init))
return true;
if (GV == 0) {
GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, 0,
- Name, 0, false, AddrSpace);
+ Name, 0, GlobalVariable::NotThreadLocal,
+ AddrSpace);
} else {
if (GV->getType()->getElementType() != Ty)
return Error(TyLoc,
GV->setConstant(IsConstant);
GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
- GV->setThreadLocal(ThreadLocal);
+ GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
+ GV->setExternallyInitialized(IsExternallyInitialized);
+ GV->setThreadLocalMode(TLM);
GV->setUnnamedAddr(UnnamedAddr);
// Parse attributes on the global.
return false;
}
+/// ParseUnnamedAttrGrp
+/// ::= 'attributes' AttrGrpID '=' '{' AttrValPair+ '}'
+bool LLParser::ParseUnnamedAttrGrp() {
+ assert(Lex.getKind() == lltok::kw_attributes);
+ LocTy AttrGrpLoc = Lex.getLoc();
+ Lex.Lex();
+
+ assert(Lex.getKind() == lltok::AttrGrpID);
+ unsigned VarID = Lex.getUIntVal();
+ std::vector<unsigned> unused;
+ LocTy BuiltinLoc;
+ Lex.Lex();
+
+ if (ParseToken(lltok::equal, "expected '=' here") ||
+ ParseToken(lltok::lbrace, "expected '{' here") ||
+ ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true,
+ BuiltinLoc) ||
+ ParseToken(lltok::rbrace, "expected end of attribute group"))
+ return true;
+
+ if (!NumberedAttrBuilders[VarID].hasAttributes())
+ return Error(AttrGrpLoc, "attribute group has no attributes");
+
+ return false;
+}
+
+/// ParseFnAttributeValuePairs
+/// ::= <attr> | <attr> '=' <value>
+bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
+ std::vector<unsigned> &FwdRefAttrGrps,
+ bool inAttrGrp, LocTy &BuiltinLoc) {
+ bool HaveError = false;
+
+ B.clear();
+
+ while (true) {
+ lltok::Kind Token = Lex.getKind();
+ if (Token == lltok::kw_builtin)
+ BuiltinLoc = Lex.getLoc();
+ switch (Token) {
+ default:
+ if (!inAttrGrp) return HaveError;
+ return Error(Lex.getLoc(), "unterminated attribute group");
+ case lltok::rbrace:
+ // Finished.
+ return false;
+
+ case lltok::AttrGrpID: {
+ // Allow a function to reference an attribute group:
+ //
+ // define void @foo() #1 { ... }
+ if (inAttrGrp)
+ HaveError |=
+ Error(Lex.getLoc(),
+ "cannot have an attribute group reference in an attribute group");
+
+ unsigned AttrGrpNum = Lex.getUIntVal();
+ if (inAttrGrp) break;
+
+ // Save the reference to the attribute group. We'll fill it in later.
+ FwdRefAttrGrps.push_back(AttrGrpNum);
+ break;
+ }
+ // Target-dependent attributes:
+ case lltok::StringConstant: {
+ std::string Attr = Lex.getStrVal();
+ Lex.Lex();
+ std::string Val;
+ if (EatIfPresent(lltok::equal) &&
+ ParseStringConstant(Val))
+ return true;
+
+ B.addAttribute(Attr, Val);
+ continue;
+ }
+
+ // Target-independent attributes:
+ case lltok::kw_align: {
+ // As a hack, we allow function alignment to be initially parsed as an
+ // attribute on a function declaration/definition or added to an attribute
+ // group and later moved to the alignment field.
+ unsigned Alignment;
+ if (inAttrGrp) {
+ Lex.Lex();
+ if (ParseToken(lltok::equal, "expected '=' here") ||
+ ParseUInt32(Alignment))
+ return true;
+ } else {
+ if (ParseOptionalAlignment(Alignment))
+ return true;
+ }
+ B.addAlignmentAttr(Alignment);
+ continue;
+ }
+ case lltok::kw_alignstack: {
+ unsigned Alignment;
+ if (inAttrGrp) {
+ Lex.Lex();
+ if (ParseToken(lltok::equal, "expected '=' here") ||
+ ParseUInt32(Alignment))
+ return true;
+ } else {
+ if (ParseOptionalStackAlignment(Alignment))
+ return true;
+ }
+ B.addStackAlignmentAttr(Alignment);
+ continue;
+ }
+ case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
+ 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_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_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
+ case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break;
+ case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
+ case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
+ case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
+ case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
+ case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
+ case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
+ case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
+ case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
+ case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
+ case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break;
+ case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break;
+ case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break;
+ case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break;
+ case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break;
+ case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break;
+ case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break;
+ case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
+
+ // Error handling.
+ case lltok::kw_inreg:
+ case lltok::kw_signext:
+ case lltok::kw_zeroext:
+ HaveError |=
+ Error(Lex.getLoc(),
+ "invalid use of attribute on a function");
+ break;
+ case lltok::kw_byval:
+ case lltok::kw_inalloca:
+ case lltok::kw_nest:
+ case lltok::kw_noalias:
+ case lltok::kw_nocapture:
+ case lltok::kw_returned:
+ case lltok::kw_sret:
+ HaveError |=
+ Error(Lex.getLoc(),
+ "invalid use of parameter-only attribute on a function");
+ break;
+ }
+
+ Lex.Lex();
+ }
+}
//===----------------------------------------------------------------------===//
// GlobalValue Reference/Resolution Routines.
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalWeakLinkage, 0, Name);
+ GlobalValue::ExternalWeakLinkage, 0, Name,
+ 0, GlobalVariable::NotThreadLocal,
+ PTy->getAddressSpace());
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
return false;
}
+/// ParseTLSModel
+/// := 'localdynamic'
+/// := 'initialexec'
+/// := 'localexec'
+bool LLParser::ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM) {
+ switch (Lex.getKind()) {
+ default:
+ return TokError("expected localdynamic, initialexec or localexec");
+ case lltok::kw_localdynamic:
+ TLM = GlobalVariable::LocalDynamicTLSModel;
+ break;
+ case lltok::kw_initialexec:
+ TLM = GlobalVariable::InitialExecTLSModel;
+ break;
+ case lltok::kw_localexec:
+ TLM = GlobalVariable::LocalExecTLSModel;
+ break;
+ }
+
+ Lex.Lex();
+ return false;
+}
+
+/// ParseOptionalThreadLocal
+/// := /*empty*/
+/// := 'thread_local'
+/// := 'thread_local' '(' tlsmodel ')'
+bool LLParser::ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM) {
+ TLM = GlobalVariable::NotThreadLocal;
+ if (!EatIfPresent(lltok::kw_thread_local))
+ return false;
+
+ TLM = GlobalVariable::GeneralDynamicTLSModel;
+ if (Lex.getKind() == lltok::lparen) {
+ Lex.Lex();
+ return ParseTLSModel(TLM) ||
+ ParseToken(lltok::rparen, "expected ')' after thread local model");
+ }
+ return false;
+}
/// ParseOptionalAddrSpace
/// := /*empty*/
ParseToken(lltok::rparen, "expected ')' in address space");
}
-/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
-/// indicates what kind of attribute list this is: 0: function arg, 1: result,
-/// 2: function attr.
-bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) {
- Attrs = Attribute::None;
- LocTy AttrLoc = Lex.getLoc();
+/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes.
+bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
+ bool HaveError = false;
+
+ B.clear();
while (1) {
- switch (Lex.getKind()) {
+ lltok::Kind Token = Lex.getKind();
+ switch (Token) {
default: // End of attributes.
- if (AttrKind != 2 && (Attrs & Attribute::FunctionOnly))
- return Error(AttrLoc, "invalid use of function-only attribute");
-
- // As a hack, we allow "align 2" on functions as a synonym for
- // "alignstack 2".
- if (AttrKind == 2 &&
- (Attrs & ~(Attribute::FunctionOnly | Attribute::Alignment)))
- return Error(AttrLoc, "invalid use of attribute on a function");
-
- if (AttrKind != 0 && (Attrs & Attribute::ParameterOnly))
- return Error(AttrLoc, "invalid use of parameter-only attribute");
-
- return false;
- case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break;
- case lltok::kw_signext: Attrs |= Attribute::SExt; break;
- case lltok::kw_inreg: Attrs |= Attribute::InReg; break;
- case lltok::kw_sret: Attrs |= Attribute::StructRet; break;
- case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break;
- case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break;
- case lltok::kw_byval: Attrs |= Attribute::ByVal; break;
- case lltok::kw_nest: Attrs |= Attribute::Nest; break;
-
- case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
- case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break;
- case lltok::kw_uwtable: Attrs |= Attribute::UWTable; break;
- case lltok::kw_returns_twice: Attrs |= Attribute::ReturnsTwice; break;
- case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
- case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
- case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
- case lltok::kw_inlinehint: Attrs |= Attribute::InlineHint; break;
- case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
- case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
- case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
- case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break;
- case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break;
- case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
- case lltok::kw_naked: Attrs |= Attribute::Naked; break;
- case lltok::kw_nonlazybind: Attrs |= Attribute::NonLazyBind; break;
- case lltok::kw_address_safety: Attrs |= Attribute::AddressSafety; break;
-
- case lltok::kw_alignstack: {
- unsigned Alignment;
- if (ParseOptionalStackAlignment(Alignment))
- return true;
- Attrs |= Attribute::constructStackAlignmentFromInt(Alignment);
- continue;
- }
-
+ return HaveError;
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
return true;
- Attrs |= Attribute::constructAlignmentFromInt(Alignment);
+ B.addAlignmentAttr(Alignment);
continue;
}
+ case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break;
+ 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;
+ case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
+ case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); 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_signext: B.addAttribute(Attribute::SExt); break;
+ case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break;
+ case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
+
+ case lltok::kw_alignstack:
+ case lltok::kw_alwaysinline:
+ case lltok::kw_builtin:
+ case lltok::kw_inlinehint:
+ case lltok::kw_minsize:
+ case lltok::kw_naked:
+ case lltok::kw_nobuiltin:
+ case lltok::kw_noduplicate:
+ case lltok::kw_noimplicitfloat:
+ case lltok::kw_noinline:
+ case lltok::kw_nonlazybind:
+ case lltok::kw_noredzone:
+ case lltok::kw_noreturn:
+ case lltok::kw_nounwind:
+ case lltok::kw_optnone:
+ case lltok::kw_optsize:
+ case lltok::kw_returns_twice:
+ case lltok::kw_sanitize_address:
+ case lltok::kw_sanitize_memory:
+ case lltok::kw_sanitize_thread:
+ case lltok::kw_ssp:
+ case lltok::kw_sspreq:
+ case lltok::kw_sspstrong:
+ case lltok::kw_uwtable:
+ HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
+ break;
+ }
+
+ Lex.Lex();
+ }
+}
+
+/// ParseOptionalReturnAttrs - Parse a potentially empty list of return attributes.
+bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
+ bool HaveError = false;
+
+ B.clear();
+
+ while (1) {
+ lltok::Kind Token = Lex.getKind();
+ switch (Token) {
+ default: // End of attributes.
+ return HaveError;
+ case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
+ case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
+ case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
+ case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
+
+ // Error handling.
+ case lltok::kw_align:
+ case lltok::kw_byval:
+ case lltok::kw_inalloca:
+ case lltok::kw_nest:
+ case lltok::kw_nocapture:
+ case lltok::kw_returned:
+ case lltok::kw_sret:
+ HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute");
+ break;
+
+ case lltok::kw_alignstack:
+ case lltok::kw_alwaysinline:
+ case lltok::kw_builtin:
+ case lltok::kw_cold:
+ case lltok::kw_inlinehint:
+ case lltok::kw_minsize:
+ case lltok::kw_naked:
+ case lltok::kw_nobuiltin:
+ case lltok::kw_noduplicate:
+ case lltok::kw_noimplicitfloat:
+ case lltok::kw_noinline:
+ case lltok::kw_nonlazybind:
+ case lltok::kw_noredzone:
+ case lltok::kw_noreturn:
+ case lltok::kw_nounwind:
+ case lltok::kw_optnone:
+ case lltok::kw_optsize:
+ case lltok::kw_returns_twice:
+ case lltok::kw_sanitize_address:
+ case lltok::kw_sanitize_memory:
+ case lltok::kw_sanitize_thread:
+ case lltok::kw_ssp:
+ case lltok::kw_sspreq:
+ case lltok::kw_sspstrong:
+ case lltok::kw_uwtable:
+ HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
+ break;
+ case lltok::kw_readnone:
+ case lltok::kw_readonly:
+ HaveError |= Error(Lex.getLoc(), "invalid use of attribute on return type");
}
+
Lex.Lex();
}
}
/// ::= 'private'
/// ::= 'linker_private'
/// ::= 'linker_private_weak'
-/// ::= 'linker_private_weak_def_auto'
/// ::= 'internal'
/// ::= 'weak'
/// ::= 'weak_odr'
/// ::= 'linkonce_odr'
/// ::= 'available_externally'
/// ::= 'appending'
-/// ::= 'dllexport'
/// ::= 'common'
-/// ::= 'dllimport'
/// ::= 'extern_weak'
/// ::= 'external'
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
case lltok::kw_linker_private_weak:
Res = GlobalValue::LinkerPrivateWeakLinkage;
break;
- case lltok::kw_linker_private_weak_def_auto:
- Res = GlobalValue::LinkerPrivateWeakDefAutoLinkage;
- 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;
}
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'
/// ::= 'fastcc'
+/// ::= 'kw_intel_ocl_bicc'
/// ::= 'coldcc'
/// ::= 'x86_stdcallcc'
/// ::= 'x86_fastcallcc'
/// ::= 'x86_thiscallcc'
+/// ::= 'x86_cdeclmethodcc'
/// ::= 'arm_apcscc'
/// ::= 'arm_aapcscc'
/// ::= 'arm_aapcs_vfpcc'
/// ::= 'msp430_intrcc'
/// ::= 'ptx_kernel'
/// ::= 'ptx_device'
+/// ::= 'spir_func'
+/// ::= 'spir_kernel'
+/// ::= 'x86_64_sysvcc'
+/// ::= 'x86_64_win64cc'
+/// ::= 'webkit_jscc'
+/// ::= 'anyregcc'
+/// ::= 'preserve_mostcc'
+/// ::= 'preserve_allcc'
/// ::= 'cc' UINT
///
bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break;
case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
case lltok::kw_x86_thiscallcc: CC = CallingConv::X86_ThisCall; break;
+ case lltok::kw_x86_cdeclmethodcc:CC = CallingConv::X86_CDeclMethod; break;
case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break;
case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break;
case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
case lltok::kw_msp430_intrcc: CC = CallingConv::MSP430_INTR; break;
case lltok::kw_ptx_kernel: CC = CallingConv::PTX_Kernel; break;
case lltok::kw_ptx_device: CC = CallingConv::PTX_Device; break;
+ case lltok::kw_spir_kernel: CC = CallingConv::SPIR_KERNEL; break;
+ case lltok::kw_spir_func: CC = CallingConv::SPIR_FUNC; break;
+ case lltok::kw_intel_ocl_bicc: CC = CallingConv::Intel_OCL_BI; break;
+ case lltok::kw_x86_64_sysvcc: CC = CallingConv::X86_64_SysV; break;
+ 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();
}
}
+ if (MDK == LLVMContext::MD_tbaa)
+ InstsWithTBAATag.push_back(Inst);
+
// If this is the end of the list, we're done.
} while (EatIfPresent(lltok::comma));
return false;
}
/// ParseOptionalCommaAlign
-/// ::=
+/// ::=
/// ::= ',' align 4
///
/// This returns with AteExtraComma set to true if it ate an excess comma at the
AteExtraComma = true;
return false;
}
-
+
if (Lex.getKind() != lltok::kw_align)
return Error(Lex.getLoc(), "expected metadata or 'align'");
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
bool &AteExtraComma) {
AteExtraComma = false;
-
+
if (Lex.getKind() != lltok::comma)
return TokError("expected ',' as start of index list");
case lltok::LocalVar: {
// Type ::= %foo
std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()];
-
+
// 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 (Lex.getUIntVal() >= NumberedTypes.size())
NumberedTypes.resize(Lex.getUIntVal()+1);
std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];
-
+
// 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 (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() &&
// Parse the argument.
LocTy ArgLoc;
Type *ArgTy = 0;
- Attributes ArgAttrs1;
- Attributes ArgAttrs2;
+ AttrBuilder ArgAttrs;
Value *V;
if (ParseType(ArgTy, ArgLoc))
return true;
// Otherwise, handle normal operands.
- if (ParseOptionalAttrs(ArgAttrs1, 0) || ParseValue(ArgTy, V, PFS))
+ if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
return true;
- ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2));
+ ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(),
+ AttrIndex++,
+ ArgAttrs)));
}
Lex.Lex(); // Lex the ')'.
} else {
LocTy TypeLoc = Lex.getLoc();
Type *ArgTy = 0;
- Attributes Attrs;
+ AttrBuilder Attrs;
std::string Name;
if (ParseType(ArgTy) ||
- ParseOptionalAttrs(Attrs, 0)) return true;
+ ParseOptionalParamAttrs(Attrs)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
if (!FunctionType::isValidArgumentType(ArgTy))
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
+ unsigned AttrIndex = 1;
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
+ AttributeSet::get(ArgTy->getContext(),
+ AttrIndex++, Attrs), Name));
while (EatIfPresent(lltok::comma)) {
// Handle ... at end of arg list.
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ParseType(ArgTy) || ParseOptionalParamAttrs(Attrs)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
- ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
+ ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
+ AttributeSet::get(ArgTy->getContext(),
+ AttrIndex++, Attrs),
+ Name));
}
}
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)
+ if (ArgList[i].Attrs.hasAttributes(i + 1))
return Error(ArgList[i].Loc,
"argument attributes invalid in function type");
}
bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) {
SmallVector<Type*, 8> Elts;
if (ParseStructBody(Elts)) return true;
-
+
Result = StructType::get(Context, Elts, Packed);
return false;
}
// If the type was already defined, diagnose the redefinition.
if (Entry.first && !Entry.second.isValid())
return Error(TypeLoc, "redefinition of type");
-
+
// If we have opaque, just return without filling in the definition for the
// struct. This counts as a definition as far as the .ll file goes.
if (EatIfPresent(lltok::kw_opaque)) {
// This type is being defined, so clear the location to indicate this.
Entry.second = SMLoc();
-
+
// If this type number has never been uttered, create it.
if (Entry.first == 0)
Entry.first = StructType::create(Context, Name);
ResultTy = Entry.first;
return false;
}
-
+
// If the type starts with '<', then it is either a packed struct or a vector.
bool isPacked = EatIfPresent(lltok::less);
if (Lex.getKind() != lltok::lbrace) {
if (Entry.first)
return Error(TypeLoc, "forward references to non-struct type");
-
+
ResultTy = 0;
if (isPacked)
return ParseArrayVectorType(ResultTy, true);
return ParseType(ResultTy);
}
-
+
// This type is being defined, so clear the location to indicate this.
Entry.second = SMLoc();
-
+
// If this type number has never been uttered, create it.
if (Entry.first == 0)
Entry.first = StructType::create(Context, Name);
-
+
StructType *STy = cast<StructType>(Entry.first);
-
+
SmallVector<Type*, 8> Body;
if (ParseStructBody(Body) ||
(isPacked && ParseToken(lltok::greater, "expected '>' in packed struct")))
return true;
-
+
STy->setBody(Body, isPacked);
ResultTy = STy;
return false;
if ((unsigned)Size != Size)
return Error(SizeLoc, "size too large for vector");
if (!VectorType::isValidElementType(EltTy))
- return Error(TypeLoc,
- "vector element type must be fp, integer or a pointer to these types");
+ return Error(TypeLoc, "invalid vector element type");
Result = VectorType::get(EltTy, unsigned(Size));
} else {
if (!ArrayType::isValidElementType(EltTy))
FunctionID.Kind = ValID::t_GlobalID;
FunctionID.UIntVal = FunctionNumber;
}
-
+
std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator
FRBAI = P.ForwardRefBlockAddresses.find(FunctionID);
if (FRBAI != P.ForwardRefBlockAddresses.end()) {
// Resolve all these references.
if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this))
return true;
-
+
P.ForwardRefBlockAddresses.erase(FRBAI);
}
}
-
+
if (!ForwardRefVals.empty())
return P.Error(ForwardRefVals.begin()->second.second,
"use of undefined value '%" + ForwardRefVals.begin()->first +
return false;
case lltok::kw_asm: {
- // ValID ::= 'asm' SideEffect? AlignStack? STRINGCONSTANT ',' STRINGCONSTANT
- bool HasSideEffect, AlignStack;
+ // ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ','
+ // STRINGCONSTANT
+ bool HasSideEffect, AlignStack, AsmDialect;
Lex.Lex();
if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
ParseOptionalToken(lltok::kw_alignstack, AlignStack) ||
+ ParseOptionalToken(lltok::kw_inteldialect, AsmDialect) ||
ParseStringConstant(ID.StrVal) ||
ParseToken(lltok::comma, "expected comma in inline asm expression") ||
ParseToken(lltok::StringConstant, "expected constraint string"))
return true;
ID.StrVal2 = Lex.getStrVal();
- ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1);
+ ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1) |
+ (unsigned(AsmDialect)<<2);
ID.Kind = ValID::t_InlineAsm;
return false;
}
Lex.Lex();
ValID Fn, Label;
- LocTy FnLoc, LabelLoc;
-
+
if (ParseToken(lltok::lparen, "expected '(' in block address expression") ||
ParseValID(Fn) ||
ParseToken(lltok::comma, "expected comma in block address expression")||
ParseValID(Label) ||
ParseToken(lltok::rparen, "expected ')' in block address expression"))
return true;
-
+
if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
return Error(Fn.Loc, "expected function name in blockaddress");
if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName)
return Error(Label.Loc, "expected basic block name in blockaddress");
-
+
// Make a global variable as a placeholder for this reference.
GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context),
false, GlobalValue::InternalLinkage,
ID.Kind = ValID::t_Constant;
return false;
}
-
+
case lltok::kw_trunc:
case lltok::kw_zext:
case lltok::kw_sext:
case lltok::kw_fptrunc:
case lltok::kw_fpext:
case lltok::kw_bitcast:
+ case lltok::kw_addrspacecast:
case lltok::kw_uitofp:
case lltok::kw_sitofp:
case lltok::kw_fptoui:
return (V == 0);
case ValID::t_InlineAsm: {
PointerType *PTy = dyn_cast<PointerType>(Ty);
- FunctionType *FTy =
+ FunctionType *FTy =
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
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, ID.UIntVal>>1);
+ V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal&1,
+ (ID.UIntVal>>1)&1, (InlineAsm::AsmDialect(ID.UIntVal>>2)));
return false;
}
case ValID::t_MDNode:
"initializer with struct type has wrong # elements");
if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct))
return Error(ID.Loc, "packed'ness of initializer and type don't match");
-
+
// Verify that the elements are compatible with the structtype.
for (unsigned i = 0, e = ID.UIntVal; i != e; ++i)
if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i))
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));
} else
/// FunctionHeader
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
/// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection
-/// OptionalAlign OptGC
+/// OptionalAlign OptGC OptionalPrefix
bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
// Parse the linkage.
LocTy LinkageLoc = Lex.getLoc();
unsigned Linkage;
unsigned Visibility;
- Attributes RetAttrs;
+ unsigned DLLStorageClass;
+ AttrBuilder RetAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc = Lex.getLoc();
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
return true;
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");
case GlobalValue::PrivateLinkage:
case GlobalValue::LinkerPrivateLinkage:
case GlobalValue::LinkerPrivateWeakLinkage:
- case GlobalValue::LinkerPrivateWeakDefAutoLinkage:
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;
SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
- Attributes FuncAttrs;
+ AttrBuilder FuncAttrs;
+ std::vector<unsigned> FwdRefAttrGrps;
+ LocTy BuiltinLoc;
std::string Section;
unsigned Alignment;
std::string GC;
bool UnnamedAddr;
LocTy UnnamedAddrLoc;
+ Constant *Prefix = 0;
if (ParseArgumentList(ArgList, isVarArg) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
&UnnamedAddrLoc) ||
- ParseOptionalAttrs(FuncAttrs, 2) ||
+ ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
+ BuiltinLoc) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
ParseOptionalAlignment(Alignment) ||
(EatIfPresent(lltok::kw_gc) &&
- ParseStringConstant(GC)))
+ ParseStringConstant(GC)) ||
+ (EatIfPresent(lltok::kw_prefix) &&
+ ParseGlobalTypeAndValue(Prefix)))
return true;
+ if (FuncAttrs.contains(Attribute::Builtin))
+ return Error(BuiltinLoc, "'builtin' attribute not valid on function");
+
// If the alignment was parsed as an attribute, move to the alignment field.
- if (FuncAttrs & Attribute::Alignment) {
- Alignment = Attribute::getAlignmentFromAttrs(FuncAttrs);
- FuncAttrs &= ~Attribute::Alignment;
+ if (FuncAttrs.hasAlignmentAttr()) {
+ Alignment = FuncAttrs.getAlignment();
+ FuncAttrs.removeAttribute(Attribute::Alignment);
}
// Okay, if we got here, the function is syntactically valid. Convert types
// and do semantic checks.
std::vector<Type*> ParamTypeList;
- SmallVector<AttributeWithIndex, 8> Attrs;
+ SmallVector<AttributeSet, 8> Attrs;
- if (RetAttrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ 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 != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs));
+ if (ArgList[i].Attrs.hasAttributes(i + 1)) {
+ AttrBuilder B(ArgList[i].Attrs, i + 1);
+ Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B));
+ }
}
- if (FuncAttrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs));
+ if (FuncAttrs.hasAttributes())
+ Attrs.push_back(AttributeSet::get(RetType->getContext(),
+ AttributeSet::FunctionIndex,
+ FuncAttrs));
- AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
+ AttributeSet PAL = AttributeSet::get(Context, Attrs);
- if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy())
+ if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy())
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
FunctionType *FT =
ForwardRefVals.find(FunctionName);
if (FRVI != ForwardRefVals.end()) {
Fn = M->getFunction(FunctionName);
+ if (!Fn)
+ return Error(FRVI->second.second, "invalid forward reference to "
+ "function as global value!");
if (Fn->getType() != PFT)
return Error(FRVI->second.second, "invalid forward reference to "
"function '" + FunctionName + "' with wrong type!");
-
+
ForwardRefVals.erase(FRVI);
} else if ((Fn = M->getFunction(FunctionName))) {
// Reject redefinitions.
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);
if (!GC.empty()) Fn->setGC(GC.c_str());
+ Fn->setPrefixData(Prefix);
+ ForwardRefAttrGroups[Fn] = FwdRefAttrGrps;
// Add all of the arguments we parsed to the function.
Function::arg_iterator ArgIt = Fn->arg_begin();
int FunctionNumber = -1;
if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1;
-
+
PerFunctionState PFS(*this, Fn, FunctionNumber);
// We need at least one basic block.
if (Lex.getKind() == lltok::rbrace)
return TokError("function body requires at least one basic block");
-
+
while (Lex.getKind() != lltok::rbrace)
if (ParseBasicBlock(PFS)) return true;
// Parse the instructions in this block until we get a terminator.
Instruction *Inst;
- SmallVector<std::pair<unsigned, MDNode *>, 4> MetadataOnInst;
do {
// This instruction may have three possibilities for a name: a) none
// specified, b) name specified "%foo =", c) number specified: "%4 =".
}
switch (ParseInstruction(Inst, BB, PFS)) {
- default: assert(0 && "Unknown ParseInstruction result!");
+ default: llvm_unreachable("Unknown ParseInstruction result!");
case InstError: return true;
case InstNormal:
BB->getInstList().push_back(Inst);
// *must* be followed by metadata.
if (ParseInstructionMetadata(Inst, &PFS))
return true;
- break;
+ break;
}
// Set the name on the instruction.
switch (Token) {
default: return Error(Loc, "expected instruction opcode");
// Terminator Instructions.
- case lltok::kw_unwind: Inst = new UnwindInst(Context); return false;
case lltok::kw_unreachable: Inst = new UnreachableInst(Context); return false;
case lltok::kw_ret: return ParseRet(Inst, BB, PFS);
case lltok::kw_br: return ParseBr(Inst, PFS);
bool NUW = EatIfPresent(lltok::kw_nuw);
bool NSW = EatIfPresent(lltok::kw_nsw);
if (!NUW) NUW = EatIfPresent(lltok::kw_nuw);
-
+
if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true;
-
+
if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
return false;
}
case lltok::kw_fadd:
case lltok::kw_fsub:
- case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
+ case lltok::kw_fmul:
+ case lltok::kw_fdiv:
+ case lltok::kw_frem: {
+ FastMathFlags FMF = EatFastMathFlagsIfPresent();
+ int Res = ParseArithmetic(Inst, PFS, KeywordVal, 2);
+ if (Res != 0)
+ return Res;
+ if (FMF.any())
+ Inst->setFastMathFlags(FMF);
+ return 0;
+ }
case lltok::kw_sdiv:
case lltok::kw_udiv:
case lltok::kw_urem:
case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1);
- case lltok::kw_fdiv:
- case lltok::kw_frem: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
case lltok::kw_and:
case lltok::kw_or:
case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal);
case lltok::kw_fptrunc:
case lltok::kw_fpext:
case lltok::kw_bitcast:
+ case lltok::kw_addrspacecast:
case lltok::kw_uitofp:
case lltok::kw_sitofp:
case lltok::kw_fptoui:
bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
if (Opc == Instruction::FCmp) {
switch (Lex.getKind()) {
- default: TokError("expected fcmp predicate (e.g. 'oeq')");
+ default: return TokError("expected fcmp predicate (e.g. 'oeq')");
case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break;
case lltok::kw_one: P = CmpInst::FCMP_ONE; break;
case lltok::kw_olt: P = CmpInst::FCMP_OLT; break;
}
} else {
switch (Lex.getKind()) {
- default: TokError("expected icmp predicate (e.g. 'eq')");
+ default: return TokError("expected icmp predicate (e.g. 'eq')");
case lltok::kw_eq: P = CmpInst::ICMP_EQ; break;
case lltok::kw_ne: P = CmpInst::ICMP_NE; break;
case lltok::kw_slt: P = CmpInst::ICMP_SLT; break;
if (ParseType(Ty, true /*void allowed*/)) return true;
Type *ResType = PFS.getFunction().getReturnType();
-
+
if (Ty->isVoidTy()) {
if (!ResType->isVoidTy())
return Error(TypeLoc, "value doesn't match function result type '" +
getTypeString(ResType) + "'");
-
+
Inst = ReturnInst::Create(Context);
return false;
}
if (ResType != RV->getType())
return Error(TypeLoc, "value doesn't match function result type '" +
getTypeString(ResType) + "'");
-
+
Inst = ReturnInst::Create(Context, RV);
return false;
}
ParseToken(lltok::comma, "expected ',' after case value") ||
ParseTypeAndBasicBlock(DestBB, PFS))
return true;
-
+
if (!SeenCases.insert(Constant))
return Error(CondLoc, "duplicate case value in switch");
if (!isa<ConstantInt>(Constant))
ParseToken(lltok::comma, "expected ',' after indirectbr address") ||
ParseToken(lltok::lsquare, "expected '[' with indirectbr"))
return true;
-
+
if (!Address->getType()->isPointerTy())
return Error(AddrLoc, "indirectbr address must have pointer type");
-
+
// Parse the destination list.
SmallVector<BasicBlock*, 16> DestList;
-
+
if (Lex.getKind() != lltok::rsquare) {
BasicBlock *DestBB;
if (ParseTypeAndBasicBlock(DestBB, PFS))
return true;
DestList.push_back(DestBB);
-
+
while (EatIfPresent(lltok::comma)) {
if (ParseTypeAndBasicBlock(DestBB, PFS))
return true;
DestList.push_back(DestBB);
}
}
-
+
if (ParseToken(lltok::rsquare, "expected ']' at end of block list"))
return true;
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
- Attributes RetAttrs, FnAttrs;
+ AttrBuilder RetAttrs, FnAttrs;
+ std::vector<unsigned> FwdRefAttrGrps;
+ LocTy NoBuiltinLoc;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
BasicBlock *NormalBB, *UnwindBB;
if (ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseOptionalAttrs(FnAttrs, 2) ||
+ ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+ NoBuiltinLoc) ||
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
ParseTypeAndBasicBlock(NormalBB, PFS) ||
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
Value *Callee;
if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
- // Set up the Attributes for the function.
- SmallVector<AttributeWithIndex, 8> Attrs;
- if (RetAttrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ // 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;
return Error(ArgList[i].Loc, "argument is not of expected type '" +
getTypeString(ExpectedTy) + "'");
Args.push_back(ArgList[i].V);
- if (ArgList[i].Attrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs));
+ if (ArgList[i].Attrs.hasAttributes(i + 1)) {
+ AttrBuilder B(ArgList[i].Attrs, i + 1);
+ Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B));
+ }
}
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
+ if (FnAttrs.hasAttributes())
+ Attrs.push_back(AttributeSet::get(RetType->getContext(),
+ AttributeSet::FunctionIndex,
+ FnAttrs));
- // Finish off the Attributes and check them
- AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
+ // Finish off the Attribute and check them
+ AttributeSet PAL = AttributeSet::get(Context, Attrs);
InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args);
II->setCallingConv(CC);
II->setAttributes(PAL);
+ ForwardRefAttrGroups[II] = FwdRefAttrGrps;
Inst = II;
return false;
}
/// ParameterList OptionalAttrs
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
- Attributes RetAttrs, FnAttrs;
+ AttrBuilder RetAttrs, FnAttrs;
+ std::vector<unsigned> FwdRefAttrGrps;
+ LocTy BuiltinLoc;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseOptionalAttrs(FnAttrs, 2))
+ ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+ BuiltinLoc))
return true;
// If RetType is a non-function pointer type, then this is the short syntax
Value *Callee;
if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true;
- // Set up the Attributes for the function.
- SmallVector<AttributeWithIndex, 8> Attrs;
- if (RetAttrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
+ // 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;
return Error(ArgList[i].Loc, "argument is not of expected type '" +
getTypeString(ExpectedTy) + "'");
Args.push_back(ArgList[i].V);
- if (ArgList[i].Attrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs));
+ if (ArgList[i].Attrs.hasAttributes(i + 1)) {
+ AttrBuilder B(ArgList[i].Attrs, i + 1);
+ Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B));
+ }
}
if (I != E)
return Error(CallLoc, "not enough parameters specified for call");
- if (FnAttrs != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
+ if (FnAttrs.hasAttributes())
+ Attrs.push_back(AttributeSet::get(RetType->getContext(),
+ AttributeSet::FunctionIndex,
+ FnAttrs));
- // Finish off the Attributes and check them
- AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
+ // Finish off the Attribute and check them
+ AttributeSet PAL = AttributeSet::get(Context, Attrs);
CallInst *CI = CallInst::Create(Callee, Args);
CI->setTailCall(isTail);
CI->setCallingConv(CC);
CI->setAttributes(PAL);
+ ForwardRefAttrGroups[CI] = FwdRefAttrGrps;
Inst = CI;
return false;
}
//===----------------------------------------------------------------------===//
/// ParseAlloc
-/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
+/// ::= 'alloca' Type (',' 'inalloca')? (',' TypeAndValue)? (',' OptionalInfo)?
int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
Value *Size = 0;
LocTy SizeLoc;
unsigned Alignment = 0;
+ bool IsInAlloca = false;
Type *Ty = 0;
if (ParseType(Ty)) return true;
bool AteExtraComma = false;
if (EatIfPresent(lltok::comma)) {
- if (Lex.getKind() == lltok::kw_align) {
- if (ParseOptionalAlignment(Alignment)) return true;
- } else if (Lex.getKind() == lltok::MetadataVar) {
- AteExtraComma = true;
- } else {
- if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
- ParseOptionalCommaAlign(Alignment, AteExtraComma))
- return true;
+ bool HaveComma = true;
+ if (EatIfPresent(lltok::kw_inalloca)) {
+ IsInAlloca = true;
+ HaveComma = EatIfPresent(lltok::comma);
+ }
+
+ if (HaveComma) {
+ if (Lex.getKind() == lltok::kw_align) {
+ if (ParseOptionalAlignment(Alignment)) return true;
+ } else if (Lex.getKind() == lltok::MetadataVar) {
+ AteExtraComma = true;
+ } else {
+ if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
+ ParseOptionalCommaAlign(Alignment, AteExtraComma))
+ return true;
+ }
}
}
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;
}
/// ParseLoad
/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)?
-/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
+/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Value *Val; LocTy Loc;
if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
- if (!Ptr->getType()->getScalarType()->isPointerTy())
+ Type *BaseType = Ptr->getType();
+ PointerType *BasePointerType = dyn_cast<PointerType>(BaseType->getScalarType());
+ if (!BasePointerType)
return Error(Loc, "base of getelementptr must be a pointer");
SmallVector<Value*, 16> Indices;
Indices.push_back(Val);
}
- if (Val && Val->getType()->isVectorTy() && Indices.size() != 1)
- return Error(EltLoc, "vector getelementptrs must have a single index");
+ if (!Indices.empty() && !BasePointerType->getElementType()->isSized())
+ return Error(Loc, "base element of getelementptr must be sized");
- if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices))
+ if (!GetElementPtrInst::getIndexedType(BaseType, Indices))
return Error(Loc, "invalid getelementptr indices");
Inst = GetElementPtrInst::Create(Ptr, Indices);
if (InBounds)
ParseTypeAndValue(Val1, Loc1, PFS) ||
ParseIndexList(Indices, AteExtraComma))
return true;
-
+
if (!Val0->getType()->isAggregateType())
return Error(Loc0, "insertvalue operand must be aggregate type");
Elts.push_back(0);
continue;
}
-
+
Value *V = 0;
if (ParseTypeAndValue(V, PFS)) return true;
Elts.push_back(V);