for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
+ // Upgrade to new EH scheme. N.B. This will go away in 3.1.
+ UpgradeExceptionHandling(M);
+
// Check debug info intrinsics.
CheckDebugInfoIntrinsics(M);
return false;
// 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) {
- Entry.first = StructType::createNamed(Context, Lex.getStrVal());
+ Entry.first = StructType::create(Context, Lex.getStrVal());
Entry.second = Lex.getLoc();
}
Result = Entry.first;
// 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) {
- Entry.first = StructType::createNamed(Context, "");
+ Entry.first = StructType::create(Context);
Entry.second = Lex.getLoc();
}
Result = Entry.first;
// If this type number has never been uttered, create it.
if (Entry.first == 0)
- Entry.first = StructType::createNamed(Context, Name);
+ Entry.first = StructType::create(Context, Name);
ResultTy = Entry.first;
return false;
}
// If this type number has never been uttered, create it.
if (Entry.first == 0)
- Entry.first = StructType::createNamed(Context, Name);
+ Entry.first = StructType::create(Context, Name);
StructType *STy = cast<StructType>(Entry.first);
case lltok::kw_alloca: return ParseAlloc(Inst, PFS);
case lltok::kw_load: return ParseLoad(Inst, PFS, false);
case lltok::kw_store: return ParseStore(Inst, PFS, false);
- case lltok::kw_cmpxchg: return ParseCmpXchg(Inst, PFS, false);
- case lltok::kw_atomicrmw: return ParseAtomicRMW(Inst, PFS, false);
+ case lltok::kw_cmpxchg: return ParseCmpXchg(Inst, PFS);
+ case lltok::kw_atomicrmw: return ParseAtomicRMW(Inst, PFS);
case lltok::kw_fence: return ParseFence(Inst, PFS);
case lltok::kw_volatile:
+ // For compatibility; canonical location is after load
if (EatIfPresent(lltok::kw_load))
return ParseLoad(Inst, PFS, true);
else if (EatIfPresent(lltok::kw_store))
return ParseStore(Inst, PFS, true);
- else if (EatIfPresent(lltok::kw_cmpxchg))
- return ParseCmpXchg(Inst, PFS, true);
- else if (EatIfPresent(lltok::kw_atomicrmw))
- return ParseAtomicRMW(Inst, PFS, true);
else
return TokError("expected 'load' or 'store'");
case lltok::kw_getelementptr: return ParseGetElementPtr(Inst, PFS);
/// ::= 'resume' TypeAndValue
bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) {
Value *Exn; LocTy ExnLoc;
- LocTy Loc = Lex.getLoc();
if (ParseTypeAndValue(Exn, ExnLoc, PFS))
return true;
- ResumeInst *RI = ResumeInst::Create(Context, Exn);
+ ResumeInst *RI = ResumeInst::Create(Exn);
Inst = RI;
return false;
}
}
/// ParseLandingPad
-/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'?
-/// (ClauseID ClauseList)+
-/// ClauseID
-/// ::= 'catch'
+/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+
+/// Clause
+/// ::= 'catch' TypeAndValue
/// ::= 'filter'
-/// ClauseList
-/// ::= TypeAndValue (',' TypeAndValue)*
+/// ::= 'filter' TypeAndValue ( ',' TypeAndValue )*
bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
Type *Ty = 0; LocTy TyLoc;
Value *PersFn; LocTy PersFnLoc;
- LocTy LPLoc = Lex.getLoc();
if (ParseType(Ty, TyLoc) ||
ParseToken(lltok::kw_personality, "expected 'personality'") ||
ParseTypeAndValue(PersFn, PersFnLoc, PFS))
return true;
- bool IsCleanup = EatIfPresent(lltok::kw_cleanup);
+ LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0);
+ LP->setCleanup(EatIfPresent(lltok::kw_cleanup));
- SmallVector<std::pair<LandingPadInst::ClauseType, Constant*>, 16> Clauses;
while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){
LandingPadInst::ClauseType CT;
- if (Lex.getKind() == lltok::kw_catch) {
+ if (EatIfPresent(lltok::kw_catch))
CT = LandingPadInst::Catch;
- ParseToken(lltok::kw_catch, "expected 'catch'");
- } else {
+ else if (EatIfPresent(lltok::kw_filter))
CT = LandingPadInst::Filter;
- ParseToken(lltok::kw_filter, "expected 'filter'");
- }
+ else
+ return TokError("expected 'catch' or 'filter' clause type");
- do {
- Value *V; LocTy VLoc;
- if (ParseTypeAndValue(V, VLoc, PFS))
- return true;
- Clauses.push_back(std::make_pair(CT, cast<Constant>(V)));
- } while (EatIfPresent(lltok::comma));
- }
+ Value *V; LocTy VLoc;
+ if (ParseTypeAndValue(V, VLoc, PFS)) {
+ delete LP;
+ return true;
+ }
- LandingPadInst *LP = LandingPadInst::Create(Ty, cast<Function>(PersFn),
- Clauses.size());
- LP->setCleanup(IsCleanup);
+ // A 'catch' type expects a non-array constant. A filter clause expects an
+ // array constant.
+ if (CT == LandingPadInst::Catch) {
+ if (isa<ArrayType>(V->getType()))
+ Error(VLoc, "'catch' clause has an invalid type");
+ } else {
+ if (!isa<ArrayType>(V->getType()))
+ Error(VLoc, "'filter' clause has an invalid type");
+ }
- for (SmallVectorImpl<std::pair<LandingPadInst::ClauseType,
- Constant*> >::iterator
- I = Clauses.begin(), E = Clauses.end(); I != E; ++I)
- LP->addClause(I->first, I->second);
+ LP->addClause(V);
+ }
Inst = LP;
return false;
}
/// ParseLoad
-/// ::= 'volatile'? 'load' TypeAndValue (',' OptionalInfo)?
+/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)?
+/// ::= 'load' 'atomic' 'volatile'? TypeAndValue
+/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
+/// Compatibility:
+/// ::= 'volatile' 'load' TypeAndValue (',' 'align' i32)?
int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) {
Value *Val; LocTy Loc;
unsigned Alignment = 0;
bool AteExtraComma = false;
+ bool isAtomic = false;
+ AtomicOrdering Ordering = NotAtomic;
+ SynchronizationScope Scope = CrossThread;
+
+ if (Lex.getKind() == lltok::kw_atomic) {
+ if (isVolatile)
+ return TokError("mixing atomic with old volatile placement");
+ isAtomic = true;
+ Lex.Lex();
+ }
+
+ if (Lex.getKind() == lltok::kw_volatile) {
+ if (isVolatile)
+ return TokError("duplicate volatile before and after store");
+ isVolatile = true;
+ Lex.Lex();
+ }
+
if (ParseTypeAndValue(Val, Loc, PFS) ||
+ ParseScopeAndOrdering(isAtomic, Scope, Ordering) ||
ParseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
if (!Val->getType()->isPointerTy() ||
!cast<PointerType>(Val->getType())->getElementType()->isFirstClassType())
return Error(Loc, "load operand must be a pointer to a first class type");
+ if (isAtomic && !Alignment)
+ return Error(Loc, "atomic load must have explicit non-zero alignment");
+ if (Ordering == Release || Ordering == AcquireRelease)
+ return Error(Loc, "atomic load cannot use Release ordering");
- Inst = new LoadInst(Val, "", isVolatile, Alignment);
+ Inst = new LoadInst(Val, "", isVolatile, Alignment, Ordering, Scope);
return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseStore
-/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)?
+
+/// ::= 'store' 'volatile'? TypeAndValue ',' TypeAndValue (',' 'align' i32)?
+/// ::= 'store' 'atomic' 'volatile'? TypeAndValue ',' TypeAndValue
+/// 'singlethread'? AtomicOrdering (',' 'align' i32)?
+/// Compatibility:
+/// ::= 'volatile' 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)?
int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
bool isVolatile) {
Value *Val, *Ptr; LocTy Loc, PtrLoc;
unsigned Alignment = 0;
bool AteExtraComma = false;
+ bool isAtomic = false;
+ AtomicOrdering Ordering = NotAtomic;
+ SynchronizationScope Scope = CrossThread;
+
+ if (Lex.getKind() == lltok::kw_atomic) {
+ if (isVolatile)
+ return TokError("mixing atomic with old volatile placement");
+ isAtomic = true;
+ Lex.Lex();
+ }
+
+ if (Lex.getKind() == lltok::kw_volatile) {
+ if (isVolatile)
+ return TokError("duplicate volatile before and after store");
+ isVolatile = true;
+ Lex.Lex();
+ }
+
if (ParseTypeAndValue(Val, Loc, PFS) ||
ParseToken(lltok::comma, "expected ',' after store operand") ||
ParseTypeAndValue(Ptr, PtrLoc, PFS) ||
+ ParseScopeAndOrdering(isAtomic, Scope, Ordering) ||
ParseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
return Error(Loc, "store operand must be a first class value");
if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
return Error(Loc, "stored value and pointer type do not match");
+ if (isAtomic && !Alignment)
+ return Error(Loc, "atomic store must have explicit non-zero alignment");
+ if (Ordering == Acquire || Ordering == AcquireRelease)
+ return Error(Loc, "atomic store cannot use Acquire ordering");
- Inst = new StoreInst(Val, Ptr, isVolatile, Alignment);
+ Inst = new StoreInst(Val, Ptr, isVolatile, Alignment, Ordering, Scope);
return AteExtraComma ? InstExtraComma : InstNormal;
}
/// ParseCmpXchg
-/// ::= 'volatile'? 'cmpxchg' TypeAndValue ',' TypeAndValue ',' TypeAndValue
-/// 'singlethread'? AtomicOrdering
-int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS,
- bool isVolatile) {
+/// ::= 'cmpxchg' 'volatile'? TypeAndValue ',' TypeAndValue ',' TypeAndValue
+/// 'singlethread'? AtomicOrdering
+int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc;
bool AteExtraComma = false;
AtomicOrdering Ordering = NotAtomic;
SynchronizationScope Scope = CrossThread;
+ bool isVolatile = false;
+
+ if (EatIfPresent(lltok::kw_volatile))
+ isVolatile = true;
+
if (ParseTypeAndValue(Ptr, PtrLoc, PFS) ||
ParseToken(lltok::comma, "expected ',' after cmpxchg address") ||
ParseTypeAndValue(Cmp, CmpLoc, PFS) ||
}
/// ParseAtomicRMW
-/// ::= 'volatile'? 'atomicrmw' BinOp TypeAndValue ',' TypeAndValue
-/// 'singlethread'? AtomicOrdering
-int LLParser::ParseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS,
- bool isVolatile) {
+/// ::= 'atomicrmw' 'volatile'? BinOp TypeAndValue ',' TypeAndValue
+/// 'singlethread'? AtomicOrdering
+int LLParser::ParseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr, *Val; LocTy PtrLoc, ValLoc;
bool AteExtraComma = false;
AtomicOrdering Ordering = NotAtomic;
SynchronizationScope Scope = CrossThread;
+ bool isVolatile = false;
AtomicRMWInst::BinOp Operation;
+
+ if (EatIfPresent(lltok::kw_volatile))
+ isVolatile = true;
+
switch (Lex.getKind()) {
default: return TokError("expected binary operation in atomicrmw");
case lltok::kw_xchg: Operation = AtomicRMWInst::Xchg; break;