Mercurial > hg > CbC > CbC_llvm
changeset 250:6ce7c7edee53
using extern setjmp if builtin is not available
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 17 Aug 2023 20:34:53 +0900 |
parents | b3a488e1e1b4 |
children | 289b6d909d63 |
files | clang/include/clang/Parse/Parser.h clang/lib/Parse/ParseCbC.cpp |
diffstat | 2 files changed, 43 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/clang/include/clang/Parse/Parser.h Sun Aug 13 12:24:34 2023 +0900 +++ b/clang/include/clang/Parse/Parser.h Thu Aug 17 20:34:53 2023 +0900 @@ -2127,6 +2127,7 @@ #ifndef noCbC StmtResult ParseCbCGotoStatement(ParsedAttributes &Attrs,StmtVector &Stmts); void CompileFromString(const char *str, StmtVector &CompoundStmts); + bool isBuiltinSetjmpDefined() ; #endif StmtResult ParseContinueStatement(); StmtResult ParseBreakStatement();
--- a/clang/lib/Parse/ParseCbC.cpp Sun Aug 13 12:24:34 2023 +0900 +++ b/clang/lib/Parse/ParseCbC.cpp Thu Aug 17 20:34:53 2023 +0900 @@ -94,39 +94,6 @@ }; } - -/// goto with environment with out logjmp -/// basic idea is prepare struct containes pointer to return value variable and stack pointer -/// -/// int main() { -/// struct __CbC_return { -/// int* i; -/// void* sp; -// void* fp; -/// } ret; -// int i; -/// if (0) { -// _CBC_RETURN: -// %fp = ret.fp; -// %rsp = ret.sp; -// i = *(ret.i); //? -// return i; -// } -/// ret.i = &i; -/// ret.sp = %rsp; -// ret.fp = %rfp; -/// __code c(int i,void* env) = _CBC_RETURN; -/// goto f(c, &ret); -/// } -/// -/// __code ret(int, void* env) { -// sp = env; -// %rax = 1; -// jmp _CBC_RETURN; -/// } -/// -/// - /// Prepare__retForGotoWithTheEnvExpr - Prepare __CbC_return, code segment for returning and some necessary statements. /// It is called when the parser find __return and statements are put into complex statement. /// @@ -137,11 +104,7 @@ /// __CbC_return = code_segment_for_return; /// __CbC_return; /// }); -/// code segment: -/// __code ret(return_type retval, void *env){ -/// *(return_type)((struct __CbC_env *)(env))->ret_p = retval; -/// longjmp((int*)(((struct __CbC_env *)env)->env),1); -/// } + ExprResult Parser::Prepare__retForGotoWithTheEnvExpr(){ if (isVoidFunction()) { // error check : function type is void or not. @@ -162,6 +125,7 @@ PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in compound statement ('{}')"); StmtVector CompoundStmts; + ConsumeAnyToken(); // eat the '__return'. // create code segment for return to C's function CreateRetCS(retcsII); @@ -181,11 +145,24 @@ CompoundStmts.push_back(innerRes.get()); Sema::CompoundScopeRAII CompoundScope(Actions); CompoundStmtRes = Actions.ActOnCompoundStmt(Loc,Loc,CompoundStmts,true); - ConsumeAnyToken(); // eat the '__return'. return Actions.ActOnStmtExpr(getCurScope(),Loc, CompoundStmtRes.get(), Loc); } +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/Token.h" + +bool Parser::isBuiltinSetjmpDefined() { + IdentifierInfo *II = PP.getIdentifierInfo("__builtin_setjmp"); + if (II != nullptr) { + int BuiltinID = II->getBuiltinID(); + + if (BuiltinID != Builtin::BI__builtin_setjmp) + return true; + } + return false; +} + /// Prepare__envForGotoWithTheEnvExpr - Prepare __CbC_environment, struct __CbC_env and some necessary statements. /// It is called when the parser find __environment and statements are put into complex statement. /// @@ -194,6 +171,7 @@ /// ({ /// volatile struct __CbC_env __CbC_environment; /// jmp_buf env_buf; --> int env_buf[64]; +/// extern int setjmp(jmp_buf); /// return_type retval; /// __CbC_environment.ret_p = &retval; /// __CbC_environment.env = &env_buf; @@ -207,6 +185,10 @@ /// void *ret_p,*env; /// } +// +// Compile from String +// make sure to CosumeToken() before call this function. +// void Parser::CompileFromString(const char *str, StmtVector &CompoundStmts){ SourceLocation Loc = Tok.getLocation(); Token TokSave = Tok; @@ -259,7 +241,11 @@ CompoundStmts.push_back(innerRes.get()); ConsumeAnyToken(); // eat the '__environment'. - CompileFromString("int env_buf[64];",CompoundStmts); // 4*64 is enough for every arch right now + if (isBuiltinSetjmpDefined()) { + CompileFromString("int env_buf[64];",CompoundStmts); // 4*64 is enough for every arch right now + } else { + CompileFromString("int env_buf[64];extern int setjmp(void *);",CompoundStmts); + } // __CbC_environment.ret_p = &retval; innerRes = CreateAssignmentStmt(__CbC_envII, retvalII, true, true, ret_pII); @@ -522,7 +508,11 @@ StmtResult InitStmt; Sema::ConditionResult Cond; - CondExp = LookupNameAndBuildExpr(CreateIdentifierInfo("__builtin_setjmp", Loc)); + if (isBuiltinSetjmpDefined()) { + CondExp = LookupNameAndBuildExpr(CreateIdentifierInfo("__builtin_setjmp", Loc)); + } else { + CondExp = LookupNameAndBuildExpr(CreateIdentifierInfo("setjmp", Loc)); + } ExprVector ArgExprs; ExprResult __envExprRes = CondExp.get(); @@ -699,7 +689,7 @@ /// CreateRetCS - Create code segment which is used for continuation with the environment. /// create these codes: /// __code ret(return_type retval, void *env){ -/// *(return_type)((struct CbC_environment *)(env))->ret_p = n; +/// *(return_type)((struct CbC_environment *)(env))->ret_p = retval; /// longjmp((void*)(((struct __CbC_environment *)env)->env),1); /// } void Parser::CreateRetCS(IdentifierInfo *csName){ @@ -779,6 +769,11 @@ ExprVector ArgExprs; CommaLocsTy CommaLocs; DeclSpec envDS(AttrFactory); + + if (! isBuiltinSetjmpDefined()) { + CompileFromString("extern void longjmp(void *,int);",FnStmts); + } + IdentifierInfo *structName = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc); setTST(&envDS, DeclSpec::TST_struct, structName); @@ -824,7 +819,11 @@ FnStmts.push_back(innerR.get()); ExprResult ljExpr,ljLHS; - ljExpr = IIToExpr(CreateIdentifierInfo("__builtin_longjmp", Loc), tok::l_paren); + if (isBuiltinSetjmpDefined()) { + ljExpr = IIToExpr(CreateIdentifierInfo("__builtin_longjmp", Loc), tok::l_paren); + } else { + ljExpr = IIToExpr(CreateIdentifierInfo("longjmp", Loc), tok::l_paren); + } ExprVector ljArgExprs; DeclSpec ljDS(AttrFactory); setTST(&ljDS, DeclSpec::TST_struct, structName);