summaryrefslogtreecommitdiff
path: root/include/clang/AST/Stmt.h
diff options
context:
space:
mode:
authorJennifer Yu <jennifer.yu@intel.com>2019-05-30 01:05:46 +0000
committerJennifer Yu <jennifer.yu@intel.com>2019-05-30 01:05:46 +0000
commit5846cacafa3a592f1745aaa20297d744c40dc56c (patch)
treefc80c301f42eca03b5b029c2d43d44a9e2eaba70 /include/clang/AST/Stmt.h
parente7fac8a0763b4595c1e8db743697857a93d2bf7d (diff)
downloadclang-5846cacafa3a592f1745aaa20297d744c40dc56c.tar.gz
clang support gnu asm goto.
Syntax: asm [volatile] goto ( AssemblerTemplate : : InputOperands : Clobbers : GotoLabels) https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html New llvm IR is "callbr" for inline asm goto instead "call" for inline asm For: asm goto("testl %0, %0; jne %l1;" :: "r"(cond)::label_true, loop); IR: callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %0, i8* blockaddress(@foo, %label_true), i8* blockaddress(@foo, %loop)) #1 to label %asm.fallthrough [label %label_true, label %loop], !srcloc !3 asm.fallthrough: Compiler need to generate: 1> a dummy constarint 'X' for each label. 2> an unique fallthrough label for each asm goto stmt " asm.fallthrough%number". Diagnostic 1> duplicate asm operand name are used in output, input and label. 2> goto out of scope. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@362045 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/AST/Stmt.h')
-rw-r--r--include/clang/AST/Stmt.h51
1 files changed, 50 insertions, 1 deletions
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 77b2173fcb..fe5d802688 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -46,6 +46,7 @@ class Attr;
class CapturedDecl;
class Decl;
class Expr;
+class AddrLabelExpr;
class LabelDecl;
class ODRHash;
class PrinterHelper;
@@ -2816,13 +2817,15 @@ class GCCAsmStmt : public AsmStmt {
StringLiteral **Constraints = nullptr;
StringLiteral **Clobbers = nullptr;
IdentifierInfo **Names = nullptr;
+ unsigned NumLabels = 0;
public:
GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
bool isvolatile, unsigned numoutputs, unsigned numinputs,
IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
StringLiteral *asmstr, unsigned numclobbers,
- StringLiteral **clobbers, SourceLocation rparenloc);
+ StringLiteral **clobbers, unsigned numlabels,
+ SourceLocation rparenloc);
/// Build an empty inline-assembly statement.
explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
@@ -2947,6 +2950,51 @@ public:
return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
}
+ //===--- Labels ---===//
+
+ bool isAsmGoto() const {
+ return NumLabels > 0;
+ }
+
+ unsigned getNumLabels() const {
+ return NumLabels;
+ }
+
+ IdentifierInfo *getLabelIdentifier(unsigned i) const {
+ return Names[i + NumInputs];
+ }
+
+ AddrLabelExpr *getLabelExpr(unsigned i) const;
+ StringRef getLabelName(unsigned i) const;
+ using labels_iterator = CastIterator<AddrLabelExpr>;
+ using const_labels_iterator = ConstCastIterator<AddrLabelExpr>;
+ using labels_range = llvm::iterator_range<labels_iterator>;
+ using labels_const_range = llvm::iterator_range<const_labels_iterator>;
+
+ labels_iterator begin_labels() {
+ return &Exprs[0] + NumInputs;
+ }
+
+ labels_iterator end_labels() {
+ return &Exprs[0] + NumInputs + NumLabels;
+ }
+
+ labels_range labels() {
+ return labels_range(begin_labels(), end_labels());
+ }
+
+ const_labels_iterator begin_labels() const {
+ return &Exprs[0] + NumInputs;
+ }
+
+ const_labels_iterator end_labels() const {
+ return &Exprs[0] + NumInputs + NumLabels;
+ }
+
+ labels_const_range labels() const {
+ return labels_const_range(begin_labels(), end_labels());
+ }
+
private:
void setOutputsAndInputsAndClobbers(const ASTContext &C,
IdentifierInfo **Names,
@@ -2954,6 +3002,7 @@ private:
Stmt **Exprs,
unsigned NumOutputs,
unsigned NumInputs,
+ unsigned NumLabels,
StringLiteral **Clobbers,
unsigned NumClobbers);