diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 10 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 29 | ||||
-rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 20 | ||||
-rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 3 |
4 files changed, 51 insertions, 11 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 2e4c304b3de..1f1ec1d687c 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5592,12 +5592,17 @@ ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) { return InputOrErr.takeError(); } - SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs()); + SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs() + + S->getNumLabels()); if (Error Err = ImportContainerChecked(S->outputs(), Exprs)) return std::move(Err); + if (Error Err = + ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs())) + return std::move(Err); + if (Error Err = ImportArrayChecked( - S->inputs(), Exprs.begin() + S->getNumOutputs())) + S->labels(), Exprs.begin() + S->getNumOutputs() + S->getNumInputs())) return std::move(Err); ExpectedSLoc AsmLocOrErr = import(S->getAsmLoc()); @@ -5623,6 +5628,7 @@ ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) { *AsmStrOrErr, S->getNumClobbers(), Clobbers.data(), + S->getNumLabels(), *RParenLocOrErr); } diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 4796ee87f72..e9a2c58f1a1 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/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]; @@ -497,6 +508,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; } @@ -614,8 +629,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; @@ -728,10 +743,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); diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 7fe0be5217d..563095f89b9 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -414,12 +414,15 @@ void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { if (Node->isVolatile()) OS << "volatile "; + if (Node->isAsmGoto()) + OS << "goto "; + OS << "("; VisitStringLiteral(Node->getAsmString()); // Outputs if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || - Node->getNumClobbers() != 0) + Node->getNumClobbers() != 0 || Node->getNumLabels() != 0) OS << " : "; for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { @@ -439,7 +442,8 @@ void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { } // Inputs - if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0) + if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 || + Node->getNumLabels() != 0) OS << " : "; for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { @@ -459,7 +463,7 @@ void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { } // Clobbers - if (Node->getNumClobbers() != 0) + if (Node->getNumClobbers() != 0 || Node->getNumLabels()) OS << " : "; for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { @@ -469,6 +473,16 @@ void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { VisitStringLiteral(Node->getClobberStringLiteral(i)); } + // Labels + if (Node->getNumLabels() != 0) + OS << " : "; + + for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) { + if (i != 0) + OS << ", "; + OS << Node->getLabelName(i); + } + OS << ");"; if (Policy.IncludeNewlines) OS << NL; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 93bdcac8b54..c5da5bfda9c 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -321,6 +321,9 @@ void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) { ID.AddInteger(S->getNumClobbers()); for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) VisitStringLiteral(S->getClobberStringLiteral(I)); + ID.AddInteger(S->getNumLabels()); + for (auto *L : S->labels()) + VisitDecl(L->getLabel()); } void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) { |