Last active
October 23, 2019 23:26
-
-
Save lpereira/bcd183d21f3d0f0cf0131a253df1c437 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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