Skip to content

Instantly share code, notes, and snippets.

@lpereira
Last active October 23, 2019 23:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lpereira/bcd183d21f3d0f0cf0131a253df1c437 to your computer and use it in GitHub Desktop.
Save lpereira/bcd183d21f3d0f0cf0131a253df1c437 to your computer and use it in GitHub Desktop.
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h (revision 315357)
+++ include/clang/AST/RecursiveASTVisitor.h (working copy)
@@ -2147,6 +2147,7 @@
DEF_TRAVERSE_STMT(DoStmt, {})
DEF_TRAVERSE_STMT(ForStmt, {})
DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(ComeFromStmt, {})
DEF_TRAVERSE_STMT(IfStmt, {})
DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
DEF_TRAVERSE_STMT(LabelStmt, {})
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h (revision 315357)
+++ include/clang/AST/Stmt.h (working copy)
@@ -1245,6 +1245,40 @@
}
};
+/// ComeFromStmt - This represents a comefrom statement.
+///
+class ComeFromStmt : public Stmt {
+ LabelDecl *Label;
+ SourceLocation ComeFromLoc;
+ SourceLocation LabelLoc;
+public:
+ ComeFromStmt(LabelDecl *label, SourceLocation CFL, SourceLocation LL)
+ : Stmt(ComeFromStmtClass), Label(label), ComeFromLoc(CFL), LabelLoc(LL) {}
+
+ /// \brief Build an empty comefrom statement.
+ explicit ComeFromStmt(EmptyShell Empty) : Stmt(ComeFromStmtClass, Empty) { }
+
+ LabelDecl *getLabel() const { return Label; }
+ void setLabel(LabelDecl *D) { Label = D; }
+
+ SourceLocation getComeFromLoc() const { return ComeFromLoc; }
+ void setComeFromLoc(SourceLocation L) { ComeFromLoc = L; }
+ SourceLocation getLabelLoc() const { return LabelLoc; }
+ void setLabelLoc(SourceLocation L) { LabelLoc = L; }
+
+ SourceLocation getLocStart() const LLVM_READONLY { return ComeFromLoc; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ComeFromStmtClass;
+ }
+
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+};
+
/// GotoStmt - This represents a direct goto.
///
class GotoStmt : public Stmt {
Index: include/clang/Basic/StmtNodes.td
===================================================================
--- include/clang/Basic/StmtNodes.td (revision 315357)
+++ include/clang/Basic/StmtNodes.td (working copy)
@@ -20,6 +20,7 @@
def ForStmt : Stmt;
def GotoStmt : Stmt;
def IndirectGotoStmt : Stmt;
+def ComeFromStmt : Stmt;
def ContinueStmt : Stmt;
def BreakStmt : Stmt;
def ReturnStmt : Stmt;
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def (revision 315357)
+++ include/clang/Basic/TokenKinds.def (working copy)
@@ -275,6 +275,7 @@
KEYWORD(float , KEYALL)
KEYWORD(for , KEYALL)
KEYWORD(goto , KEYALL)
+KEYWORD(comefrom , KEYALL)
KEYWORD(if , KEYALL)
KEYWORD(inline , KEYC99|KEYCXX|KEYGNU)
KEYWORD(int , KEYALL)
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h (revision 315357)
+++ include/clang/Parse/Parser.h (working copy)
@@ -1764,6 +1764,7 @@
StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
StmtResult ParseDoStatement();
StmtResult ParseForStatement(SourceLocation *TrailingElseLoc);
+ StmtResult ParseComeFromStatement();
StmtResult ParseGotoStatement();
StmtResult ParseContinueStatement();
StmtResult ParseBreakStatement();
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h (revision 315357)
+++ include/clang/Sema/Sema.h (working copy)
@@ -3754,6 +3754,9 @@
BuildForRangeKind Kind);
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body);
+ StmtResult ActOnComeFromStmt(SourceLocation GotoLoc,
+ SourceLocation LabelLoc,
+ LabelDecl *TheDecl);
StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
SourceLocation LabelLoc,
LabelDecl *TheDecl);
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h (revision 315357)
+++ include/clang-c/Index.h (working copy)
@@ -2476,6 +2476,10 @@
/** \brief OpenMP target teams distribute simd directive.
*/
CXCursor_OMPTargetTeamsDistributeSimdDirective = 279,
+
+ /** \brief Intercal compatibility.
+ */
+ CXCursor_ComeFromStmt = 280,
CXCursor_LastStmt = CXCursor_OMPTargetTeamsDistributeSimdDirective,
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp (revision 315357)
+++ lib/AST/StmtPrinter.cpp (working copy)
@@ -342,6 +342,11 @@
PrintRawCompoundStmt(Node->getSubStmt());
}
+void StmtPrinter::VisitComeFromStmt(ComeFromStmt *Node) {
+ Indent() << "comefrom " << Node->getLabel()->getName() << ";";
+ if (Policy.IncludeNewlines) OS << "\n";
+}
+
void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
Indent() << "goto " << Node->getLabel()->getName() << ";";
if (Policy.IncludeNewlines) OS << "\n";
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp (revision 315357)
+++ lib/CodeGen/CGStmt.cpp (working copy)
@@ -87,6 +87,7 @@
case Stmt::LabelStmtClass:
case Stmt::AttributedStmtClass:
case Stmt::GotoStmtClass:
+ case Stmt::ComeFromStmtClass:
case Stmt::BreakStmtClass:
case Stmt::ContinueStmtClass:
case Stmt::DefaultStmtClass:
@@ -347,6 +348,7 @@
case Stmt::AttributedStmtClass:
EmitAttributedStmt(cast<AttributedStmt>(*S)); break;
case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
+ case Stmt::ComeFromStmtClass: EmitComeFromStmt(cast<ComeFromStmt>(*S)); break;
case Stmt::BreakStmtClass: EmitBreakStmt(cast<BreakStmt>(*S)); break;
case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break;
case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break;
@@ -550,8 +552,13 @@
void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
- EmitLabel(S.getDecl());
- EmitStmt(S.getSubStmt());
+ JumpDest &Dest = ComeFromMap[S.getDecl()];
+ if (Dest.isValid()) {
+ EmitBranchThroughCleanup(Dest);
+ } else {
+ EmitLabel(S.getDecl());
+ EmitStmt(S.getSubStmt());
+ }
}
void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
@@ -568,6 +575,11 @@
EmitBranchThroughCleanup(getJumpDestForLabel(S.getLabel()));
}
+void CodeGenFunction::EmitComeFromStmt(const ComeFromStmt &S) {
+ auto L = S.getLabel();
+ EmitLabel(L);
+ ComeFromMap[L] = getJumpDestForLabel(L);
+}
void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
if (const LabelDecl *Target = S.getConstantTarget()) {
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h (revision 315357)
+++ lib/CodeGen/CodeGenFunction.h (working copy)
@@ -1077,6 +1077,9 @@
/// LabelMap - This keeps track of the LLVM basic block for each C label.
llvm::DenseMap<const LabelDecl*, JumpDest> LabelMap;
+ /// ComeFromMap - This keeps track of the LLVM basic block for each comefrom stmt.
+ llvm::DenseMap<const LabelDecl*, JumpDest> ComeFromMap;
+
// BreakContinueStack - This keeps track of where break and continue
// statements should jump to.
struct BreakContinue {
@@ -2587,6 +2590,7 @@
void EmitLabelStmt(const LabelStmt &S);
void EmitAttributedStmt(const AttributedStmt &S);
+ void EmitComeFromStmt(const ComeFromStmt &S);
void EmitGotoStmt(const GotoStmt &S);
void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
void EmitIfStmt(const IfStmt &S);
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp (revision 315357)
+++ lib/Parse/ParseStmt.cpp (working copy)
@@ -254,6 +254,10 @@
Res = ParseGotoStatement();
SemiError = "goto";
break;
+ case tok::kw_comefrom: // Intercal compatibility
+ Res = ParseComeFromStatement();
+ SemiError = "comefrom";
+ break;
case tok::kw_continue: // C99 6.8.6.2: continue-statement
Res = ParseContinueStatement();
SemiError = "continue";
@@ -1858,6 +1862,31 @@
return Res;
}
+/// ParseComeFromStatement
+/// jump-statement:
+/// 'comefrom' identifier ';'
+///
+/// Note: this lets the caller parse the end ';'.
+///
+StmtResult Parser::ParseComeFromStatement() {
+ assert(Tok.is(tok::kw_comefrom) && "Not a comefrom stmt!");
+ SourceLocation ComeFromLoc = ConsumeToken(); // eat the 'comefrom'.
+
+ StmtResult Res;
+ if (Tok.is(tok::identifier)) {
+ LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
+ Tok.getLocation());
+ Res = Actions.ActOnComeFromStmt(ComeFromLoc, Tok.getLocation(), LD);
+ ConsumeToken();
+ } else {
+ Diag(Tok, diag::err_expected) << tok::identifier;
+ return StmtError();
+ }
+
+ return Res;
+}
+
+
/// ParseContinueStatement
/// jump-statement:
/// 'continue' ';'
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp (revision 315357)
+++ lib/Sema/SemaStmt.cpp (working copy)
@@ -1428,6 +1428,10 @@
FoundDecl = true;
}
+ void VisitComeFromStmt(ComeFromStmt *S) {
+ FoundDecl = true;
+ }
+
void VisitCastExpr(CastExpr *E) {
if (E->getCastKind() == CK_LValueToRValue)
CheckLValueToRValueCast(E->getSubExpr());
@@ -2771,6 +2775,14 @@
return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
}
+StmtResult Sema::ActOnComeFromStmt(SourceLocation ComeFromLoc,
+ SourceLocation LabelLoc,
+ LabelDecl *TheDecl) {
+ getCurFunction()->setHasBranchIntoScope();
+ TheDecl->markUsed(Context);
+ return new (Context) ComeFromStmt(TheDecl, ComeFromLoc, LabelLoc);
+}
+
StmtResult
Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
Expr *E) {
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h (revision 315357)
+++ lib/Sema/TreeTransform.h (working copy)
@@ -6766,6 +6766,12 @@
template<typename Derived>
StmtResult
+TreeTransform<Derived>::TransformComeFromStmt(ComeFromStmt *S) {
+ return S;
+}
+
+template<typename Derived>
+StmtResult
TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
S->getLabel());
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp (revision 315357)
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp (working copy)
@@ -952,6 +952,7 @@
case Stmt::DoStmtClass:
case Stmt::ForStmtClass:
case Stmt::GotoStmtClass:
+ case Stmt::ComeFromStmtClass:
case Stmt::IfStmtClass:
case Stmt::IndirectGotoStmtClass:
case Stmt::LabelStmtClass:
Index: tools/libclang/CXCursor.cpp
===================================================================
--- tools/libclang/CXCursor.cpp (revision 315357)
+++ tools/libclang/CXCursor.cpp (working copy)
@@ -140,6 +140,10 @@
K = CXCursor_ForStmt;
break;
+ case Stmt::ComeFromStmtClass:
+ K = CXCursor_ComeFromStmt;
+ break;
+
case Stmt::GotoStmtClass:
K = CXCursor_GotoStmt;
break;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment