//===----------------------------------------------------------------------===//
#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;
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.
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
+ UpgradeDebugInfo(*M);
+
return false;
}
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: // FIXME: backwards compat.
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_linkonce_odr_auto_hide: // 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");
}
/// 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)
}
/// 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)
+ 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 IsConstant, UnnamedAddr;
+ bool IsConstant, UnnamedAddr, IsExternallyInitialized;
GlobalVariable::ThreadLocalMode TLM;
LocTy UnnamedAddrLoc;
+ LocTy IsExternallyInitializedLoc;
LocTy TyLoc;
Type *Ty = 0;
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;
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);
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.
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(AttrBuilder &B, unsigned AttrKind) {
- LocTy AttrLoc = Lex.getLoc();
+/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes.
+bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
bool HaveError = false;
B.clear();
switch (Token) {
default: // End of attributes.
return HaveError;
- case lltok::kw_zeroext: B.addAttribute(Attributes::ZExt); break;
- case lltok::kw_signext: B.addAttribute(Attributes::SExt); break;
- case lltok::kw_inreg: B.addAttribute(Attributes::InReg); break;
- case lltok::kw_sret: B.addAttribute(Attributes::StructRet); break;
- case lltok::kw_noalias: B.addAttribute(Attributes::NoAlias); break;
- case lltok::kw_nocapture: B.addAttribute(Attributes::NoCapture); break;
- case lltok::kw_byval: B.addAttribute(Attributes::ByVal); break;
- case lltok::kw_nest: B.addAttribute(Attributes::Nest); break;
-
- case lltok::kw_noreturn: B.addAttribute(Attributes::NoReturn); break;
- case lltok::kw_nounwind: B.addAttribute(Attributes::NoUnwind); break;
- case lltok::kw_uwtable: B.addAttribute(Attributes::UWTable); break;
- case lltok::kw_returns_twice: B.addAttribute(Attributes::ReturnsTwice); break;
- case lltok::kw_noinline: B.addAttribute(Attributes::NoInline); break;
- case lltok::kw_readnone: B.addAttribute(Attributes::ReadNone); break;
- case lltok::kw_readonly: B.addAttribute(Attributes::ReadOnly); break;
- case lltok::kw_inlinehint: B.addAttribute(Attributes::InlineHint); break;
- case lltok::kw_alwaysinline: B.addAttribute(Attributes::AlwaysInline); break;
- case lltok::kw_optsize: B.addAttribute(Attributes::OptimizeForSize); break;
- case lltok::kw_ssp: B.addAttribute(Attributes::StackProtect); break;
- case lltok::kw_sspreq: B.addAttribute(Attributes::StackProtectReq); break;
- case lltok::kw_noredzone: B.addAttribute(Attributes::NoRedZone); break;
- case lltok::kw_noimplicitfloat: B.addAttribute(Attributes::NoImplicitFloat); break;
- case lltok::kw_naked: B.addAttribute(Attributes::Naked); break;
- case lltok::kw_nonlazybind: B.addAttribute(Attributes::NonLazyBind); break;
- case lltok::kw_address_safety: B.addAttribute(Attributes::AddressSafety); break;
- case lltok::kw_minsize: B.addAttribute(Attributes::MinSize); break;
-
- case lltok::kw_alignstack: {
- unsigned Alignment;
- if (ParseOptionalStackAlignment(Alignment))
- return true;
- B.addStackAlignmentAttr(Alignment);
- continue;
- }
-
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(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;
}
- // Perform some error checking.
+ 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:
- if (AttrKind == 2)
- HaveError |= Error(AttrLoc, "invalid use of attribute on a function");
- break;
- case lltok::kw_align:
- // As a hack, we allow "align 2" on functions as a synonym for
- // "alignstack 2".
- break;
+ 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;
- // Parameter Only:
- case lltok::kw_sret:
- case lltok::kw_nocapture:
+ // Error handling.
+ case lltok::kw_align:
case lltok::kw_byval:
+ case lltok::kw_inalloca:
case lltok::kw_nest:
- if (AttrKind != 0)
- HaveError |= Error(AttrLoc, "invalid use of parameter-only attribute");
+ case lltok::kw_nocapture:
+ case lltok::kw_returned:
+ case lltok::kw_sret:
+ HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute");
break;
- // Function Only:
+ 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_readnone:
- case lltok::kw_readonly:
- case lltok::kw_noinline:
- case lltok::kw_alwaysinline:
+ 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_noredzone:
- case lltok::kw_noimplicitfloat:
- case lltok::kw_naked:
- case lltok::kw_inlinehint:
- case lltok::kw_alignstack:
+ case lltok::kw_sspstrong:
case lltok::kw_uwtable:
- case lltok::kw_nonlazybind:
- case lltok::kw_returns_twice:
- case lltok::kw_address_safety:
- case lltok::kw_minsize:
- if (AttrKind != 2)
- HaveError |= Error(AttrLoc, "invalid use of function-only attribute");
+ 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();
/// ::= 'weak_odr'
/// ::= 'linkonce'
/// ::= 'linkonce_odr'
-/// ::= 'linkonce_odr_auto_hide'
/// ::= 'available_externally'
/// ::= 'appending'
-/// ::= 'dllexport'
/// ::= 'common'
-/// ::= 'dllimport'
/// ::= 'extern_weak'
/// ::= 'external'
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break;
case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break;
case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break;
- case lltok::kw_linkonce_odr_auto_hide:
- case lltok::kw_linker_private_weak_def_auto: // FIXME: For backwards compat.
- Res = GlobalValue::LinkOnceODRAutoHideLinkage;
- break;
case lltok::kw_available_externally:
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'
/// ::= 'x86_stdcallcc'
/// ::= 'x86_fastcallcc'
/// ::= 'x86_thiscallcc'
+/// ::= 'x86_cdeclmethodcc'
/// ::= 'arm_apcscc'
/// ::= 'arm_aapcscc'
/// ::= 'arm_aapcs_vfpcc'
/// ::= '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_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;
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() &&
return true;
// Otherwise, handle normal operands.
- if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS))
+ if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
return true;
- ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(V->getContext(),
- ArgAttrs)));
+ ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(),
+ AttrIndex++,
+ ArgAttrs)));
}
Lex.Lex(); // Lex the ')'.
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");
+ unsigned AttrIndex = 1;
ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
- Attributes::get(ArgTy->getContext(),
- Attrs), Name));
+ 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");
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy,
- Attributes::get(ArgTy->getContext(), Attrs),
+ 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.hasAttributes())
+ if (ArgList[i].Attrs.hasAttributes(i + 1))
return Error(ArgList[i].Loc,
"argument attributes invalid in function type");
}
return false;
case lltok::kw_asm: {
- // ValID ::= 'asm' SideEffect? AlignStack? STRINGCONSTANT ',' STRINGCONSTANT
+ // ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ','
+ // STRINGCONSTANT
bool HasSideEffect, AlignStack, AsmDialect;
Lex.Lex();
if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
Lex.Lex();
ValID Fn, Label;
- LocTy FnLoc, LabelLoc;
if (ParseToken(lltok::lparen, "expected '(' in block address expression") ||
ParseValID(Fn) ||
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:
/// 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;
+ 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::AvailableExternallyLinkage:
case GlobalValue::LinkOnceAnyLinkage:
case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::LinkOnceODRAutoHideLinkage:
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;
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.hasAlignmentAttr()) {
Alignment = FuncAttrs.getAlignment();
- FuncAttrs.removeAttribute(Attributes::Alignment);
+ 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.hasAttributes())
- Attrs.push_back(
- AttributeWithIndex::get(AttrListPtr::ReturnIndex,
- Attributes::get(RetType->getContext(),
- RetAttrs)));
+ 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.hasAttributes())
- 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.hasAttributes())
- Attrs.push_back(
- AttributeWithIndex::get(AttrListPtr::FunctionIndex,
- Attributes::get(RetType->getContext(),
- FuncAttrs)));
+ Attrs.push_back(AttributeSet::get(RetType->getContext(),
+ AttributeSet::FunctionIndex,
+ FuncAttrs));
- AttrListPtr PAL = AttrListPtr::get(Attrs);
+ AttributeSet PAL = AttributeSet::get(Context, Attrs);
- if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) &&
- !RetType->isVoidTy())
+ if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy())
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
FunctionType *FT =
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();
// 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 =".
}
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;
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
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;
+ // Set up the Attribute for the function.
+ SmallVector<AttributeSet, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(
- AttributeWithIndex::get(AttrListPtr::ReturnIndex,
- Attributes::get(Callee->getContext(),
- RetAttrs)));
+ 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.hasAttributes())
- 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.hasAttributes())
- Attrs.push_back(
- AttributeWithIndex::get(AttrListPtr::FunctionIndex,
- Attributes::get(Callee->getContext(),
- FnAttrs)));
+ Attrs.push_back(AttributeSet::get(RetType->getContext(),
+ AttributeSet::FunctionIndex,
+ FnAttrs));
- // Finish off the Attributes and check them
- AttrListPtr PAL = AttrListPtr::get(Attrs);
+ // 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;
}
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
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;
+ // Set up the Attribute for the function.
+ SmallVector<AttributeSet, 8> Attrs;
if (RetAttrs.hasAttributes())
- Attrs.push_back(
- AttributeWithIndex::get(AttrListPtr::ReturnIndex,
- Attributes::get(Callee->getContext(),
- RetAttrs)));
+ 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.hasAttributes())
- 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.hasAttributes())
- Attrs.push_back(
- AttributeWithIndex::get(AttrListPtr::FunctionIndex,
- Attributes::get(Callee->getContext(),
- FnAttrs)));
+ Attrs.push_back(AttributeSet::get(RetType->getContext(),
+ AttributeSet::FunctionIndex,
+ FnAttrs));
- // Finish off the Attributes and check them
- AttrListPtr PAL = AttrListPtr::get(Attrs);
+ // 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;
}
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 (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices))
+ if (!Indices.empty() && !BasePointerType->getElementType()->isSized())
+ return Error(Loc, "base element of getelementptr must be sized");
+
+ if (!GetElementPtrInst::getIndexedType(BaseType, Indices))
return Error(Loc, "invalid getelementptr indices");
Inst = GetElementPtrInst::Create(Ptr, Indices);
if (InBounds)