summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTImporter.cpp10
-rw-r--r--clang/lib/AST/Stmt.cpp29
-rw-r--r--clang/lib/AST/StmtPrinter.cpp20
-rw-r--r--clang/lib/AST/StmtProfile.cpp3
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) {
OpenPOWER on IntegriCloud