diff options
Diffstat (limited to 'lib/AST/Stmt.cpp')
-rw-r--r-- | lib/AST/Stmt.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 68a5a2d6ab..0a4d403106 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -444,6 +444,14 @@ void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) { Exprs[i + NumOutputs] = E; } +AddrLabelExpr *GCCAsmStmt::getLabelExpr(unsigned i) const { + return cast<AddrLabelExpr>(Exprs[i + NumInputs]); +} + +StringRef GCCAsmStmt::getLabelName(unsigned i) const { + return getLabelExpr(i)->getLabel()->getName(); +} + /// getInputConstraint - Return the specified input constraint. Unlike output /// constraints, these can be empty. StringRef GCCAsmStmt::getInputConstraint(unsigned i) const { @@ -456,13 +464,16 @@ void GCCAsmStmt::setOutputsAndInputsAndClobbers(const ASTContext &C, Stmt **Exprs, unsigned NumOutputs, unsigned NumInputs, + unsigned NumLabels, StringLiteral **Clobbers, unsigned NumClobbers) { this->NumOutputs = NumOutputs; this->NumInputs = NumInputs; this->NumClobbers = NumClobbers; + this->NumLabels = NumLabels; + assert(!(NumOutputs && NumLabels) && "asm goto cannot have outputs"); - unsigned NumExprs = NumOutputs + NumInputs; + unsigned NumExprs = NumOutputs + NumInputs + NumLabels; C.Deallocate(this->Names); this->Names = new (C) IdentifierInfo*[NumExprs]; @@ -498,6 +509,10 @@ int GCCAsmStmt::getNamedOperand(StringRef SymbolicName) const { if (getInputName(i) == SymbolicName) return getNumOutputs() + NumPlusOperands + i; + for (unsigned i = 0, e = getNumLabels(); i != e; ++i) + if (getLabelName(i) == SymbolicName) + return i + getNumInputs(); + // Not found. return -1; } @@ -615,8 +630,8 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces, while (CurPtr != StrEnd && isDigit(*CurPtr)) N = N*10 + ((*CurPtr++)-'0'); - unsigned NumOperands = - getNumOutputs() + getNumPlusOperands() + getNumInputs(); + unsigned NumOperands = getNumOutputs() + getNumPlusOperands() + + getNumInputs() + getNumLabels(); if (N >= NumOperands) { DiagOffs = CurPtr-StrStart-1; return diag::err_asm_invalid_operand_number; @@ -729,10 +744,12 @@ GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, unsigned numinputs, IdentifierInfo **names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, - StringLiteral **clobbers, SourceLocation rparenloc) + StringLiteral **clobbers, unsigned numlabels, + SourceLocation rparenloc) : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs, - numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) { - unsigned NumExprs = NumOutputs + NumInputs; + numinputs, numclobbers), + RParenLoc(rparenloc), AsmStr(asmstr), NumLabels(numlabels) { + unsigned NumExprs = NumOutputs + NumInputs + NumLabels; Names = new (C) IdentifierInfo*[NumExprs]; std::copy(names, names + NumExprs, Names); |