Mercurial > hg > CbC > CbC_llvm
changeset 57:88b0e1f890d7
Use complex statements for goto with the environment
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 02 Feb 2014 16:01:05 +0900 |
parents | bdef5c940791 |
children | 01c954c1b51b |
files | tools/clang/include/clang/Parse/Parser.h tools/clang/lib/Parse/ParseCbC.cpp tools/clang/lib/Parse/ParseExpr.cpp tools/clang/lib/Parse/Parser.cpp |
diffstat | 4 files changed, 139 insertions(+), 115 deletions(-) [+] |
line wrap: on
line diff
--- a/tools/clang/include/clang/Parse/Parser.h Thu Jan 23 23:14:57 2014 +0900 +++ b/tools/clang/include/clang/Parse/Parser.h Sun Feb 02 16:01:05 2014 +0900 @@ -1505,7 +1505,6 @@ #ifndef noCbC // for CbC StmtVector* Stmtsp; const char* curFuncName; - bool preparedGotoWithTheEnv; #endif StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0); @@ -1704,12 +1703,11 @@ void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback); #ifndef noCbC - bool PrepareForGotoWithTheEnv(); bool CreateRetFunction(); void Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS); IdentifierInfo* CreateIdentifierInfo(const char* Name, SourceLocation Loc); Decl* Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name); - ExprResult LookupAndDeclareName(IdentifierInfo *II); + ExprResult LookupAndDeclareName(IdentifierInfo *II = 0, bool IsAddressOfOperand = false); ExprResult LookupMemberAndBuildExpr(IdentifierInfo *II, Expr* Base, bool IsArrow); StmtResult CreateSjForContinuationWithEnv(); StmtResult CreateAssignmentStmt(IdentifierInfo* LHSII = 0, IdentifierInfo* RHSII = 0, unsigned LHSFlags = 0, @@ -1721,6 +1719,10 @@ Decl* HandleDeclAndChangeDeclType(Declarator &D); void setTST(DeclSpec *DS = 0, DeclSpec::TST T = DeclSpec::TST_int, IdentifierInfo *Name = 0); void IncludeHeader(const char* HeaderName); + ExprResult IIToExpr(IdentifierInfo *II, tok::TokenKind Kind); + StmtResult CreateComplexStmtRet(IdentifierInfo *II, bool IsAddressOfOperand); + ExprResult Prepare__retForGotoWithTheEnvExpr(); + ExprResult Prepare__envForGotoWithTheEnvExpr(); #endif bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
--- a/tools/clang/lib/Parse/ParseCbC.cpp Thu Jan 23 23:14:57 2014 +0900 +++ b/tools/clang/lib/Parse/ParseCbC.cpp Sun Feb 02 16:01:05 2014 +0900 @@ -5,29 +5,14 @@ #include "clang/AST/ASTContext.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/PrettyStackTrace.h" -#include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" -#include "clang/Sema/TypoCorrection.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCObjectFileInfo.h" -#include "llvm/MC/MCParser/MCAsmParser.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCTargetAsmParser.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/ADT/SmallString.h" #include "clang/Sema/Lookup.h" #include "clang/Lex/LiteralSupport.h" #include "clang/AST/ASTConsumer.h" -#include <cmath> #include <sstream> #include <string> #include "CbCHelper.h" @@ -114,59 +99,88 @@ } -bool Parser::PrepareForGotoWithTheEnv(){ - StmtResult Res; +ExprResult Parser::Prepare__retForGotoWithTheEnvExpr(){ + StmtResult innerRes; SourceLocation Loc = Tok.getLocation(); + IdentifierInfo *__CbC_retII = CreateIdentifierInfo(__CBC_RETURN_NAME, Loc); + IdentifierInfo *retcsII = CreateUniqueIdentifierInfo(__CBC_RET_CODE_BASE_NAME, Loc); + Create__CbC_envStruct(Loc, AS_none); - IdentifierInfo *bufII, *retvalII, *structII, *__CbC_envII, *__CbC_retII,*envII, *ret_pII, *retcsII; - bufII = CreateUniqueIdentifierInfo(__CBC_BUF_NAME, Loc); - retvalII = CreateUniqueIdentifierInfo(__CBC_RETVAL_NAME, Loc); - structII = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc); - __CbC_envII = CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc); - __CbC_retII = CreateIdentifierInfo(__CBC_RETURN_NAME, Loc); - envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc); - ret_pII = CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc); - retcsII = CreateUniqueIdentifierInfo(__CBC_RET_CODE_BASE_NAME, Loc); + Actions.ActOnStartStmtExpr(); + StmtResult CompoundStmtRes; + ParseScope CompoundScope(this, Scope::DeclScope); + PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in compound statement ('{}')"); + StmtVector CompoundStmts; if (CreateRetFunction()) { // error check : function type is void or not. Diag(Tok, diag::err_cannot_use_goto_with_env); - return true; + return ExprError(); } - Res = CreateDeclStmt(__CbC_retII, CbCSpace::CbCReturnFunc, DeclSpec::TST___code); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); - - Res = CreateDeclStmt(__CbC_envII, 0, DeclSpec::TST_struct, structII); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); + innerRes = CreateDeclStmt(__CbC_retII, CbCSpace::CbCReturnFunc, DeclSpec::TST___code); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); - Res = CreateDeclStmt(bufII, 0, DeclSpec::TST_typename, CreateIdentifierInfo("jmp_buf", Loc)); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); - - Res = CreateDeclStmt(retvalII, CbCSpace::CopyParentType); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); + innerRes = CreateAssignmentStmt(__CbC_retII, retcsII); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); - Res = CreateAssignmentStmt(__CbC_envII, retvalII, CbCSpace::HasPeriod, CbCSpace::HasAmp, ret_pII); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); - - Res = CreateAssignmentStmt(__CbC_envII, bufII, CbCSpace::HasPeriod, 0, envII); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); + innerRes = CreateComplexStmtRet(__CbC_retII, false); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); - Res = CreateSjForContinuationWithEnv(); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); - - Res = CreateAssignmentStmt(__CbC_retII, retcsII); - if (Res.isUsable()) - Stmtsp->push_back(Res.release()); - return false; + CompoundStmtRes = Actions.ActOnCompoundStmt(Loc,Loc,CompoundStmts,true); + ConsumeToken(); // eat the '__return'. + return Actions.ActOnStmtExpr(Loc, CompoundStmtRes.take(), Loc); } +ExprResult Parser::Prepare__envForGotoWithTheEnvExpr(){ + StmtResult innerRes; + SourceLocation Loc = Tok.getLocation(); + IdentifierInfo *bufII = CreateUniqueIdentifierInfo(__CBC_BUF_NAME, Loc); + IdentifierInfo *retvalII = CreateUniqueIdentifierInfo(__CBC_RETVAL_NAME, Loc); + IdentifierInfo *structII = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc); + IdentifierInfo *__CbC_envII = CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc); + IdentifierInfo *envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc); + IdentifierInfo *ret_pII = CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc); + Create__CbC_envStruct(Loc, AS_none); + Actions.ActOnStartStmtExpr(); + ParseScope CompoundScope(this, Scope::DeclScope); + PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in compound statement ('{}')"); + StmtVector CompoundStmts; + + innerRes = CreateDeclStmt(__CbC_envII, 0, DeclSpec::TST_struct, structII); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); + + innerRes = CreateDeclStmt(retvalII, CbCSpace::CopyParentType); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); + + innerRes = CreateDeclStmt(bufII, 0, DeclSpec::TST_typename, CreateIdentifierInfo("jmp_buf", Loc)); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); + + innerRes = CreateAssignmentStmt(__CbC_envII, retvalII, CbCSpace::HasPeriod, CbCSpace::HasAmp, ret_pII); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); + + innerRes = CreateAssignmentStmt(__CbC_envII, bufII, CbCSpace::HasPeriod, 0, envII); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); + + innerRes = CreateSjForContinuationWithEnv(); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); + + innerRes = CreateComplexStmtRet(__CbC_envII, true); + if (innerRes.isUsable()) + CompoundStmts.push_back(innerRes.release()); + + StmtResult CompoundStmtRes = Actions.ActOnCompoundStmt(Loc,Loc,CompoundStmts,true); + ConsumeToken(); // eat the '__environment'. + return Actions.ActOnStmtExpr(Loc, CompoundStmtRes.take(), Loc); +} StmtResult Parser::CreateAssignmentStmt(IdentifierInfo* LHSII,IdentifierInfo* RHSII,unsigned LHSFlags,unsigned RHSFlags, IdentifierInfo* extraLHSII,IdentifierInfo* extraRHSII){ @@ -413,13 +427,12 @@ return IfRes; } -ExprResult Parser::LookupAndDeclareName(IdentifierInfo *II){ +ExprResult Parser::LookupAndDeclareName(IdentifierInfo *II, bool IsAddressOfOperand){ SourceLocation Loc = Tok.getLocation(); UnqualifiedId Name; CXXScopeSpec SS; SourceLocation TemplateKWLoc; ExternalSpace::CastExpressionIdValidator Validator(false,true); - bool IsAddressOfOperand = false; Name.setIdentifier(II, Loc); return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, false, IsAddressOfOperand, &Validator); } @@ -450,19 +463,26 @@ /// Create__CbC_envStruct - This method create "struct __CbC_env" which is used to continuation with environment. /// If the __CbC_env has been already defined, it doesn't create __CbC_env again. void Parser::Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS) { - ParsingDeclSpec SDS(*this); - if (SDS.getSourceRange().isInvalid()) { - SDS.SetRangeStart(Loc); - SDS.SetRangeEnd(Loc); - } + IdentifierInfo *Name = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc); - // Check previous definition. If the __CbC_env has been already defined, we have not to create again. LookupResult Previous(Actions, Name, Loc, Actions.LookupTagName, Actions.ForRedeclaration); if(Actions.LookupName(Previous, getCurScope())) return; - + + Scope *SavedScope = getCurScope(); + DeclContext *SavedContext = Actions.CurContext; + sema::FunctionScopeInfo *SavedFSI = Actions.FunctionScopes.pop_back_val(); + Actions.CurContext = static_cast<DeclContext *>(Actions.Context.getTranslationUnitDecl()); + Scope *TopScope = getCurScope(); + while(TopScope->getParent() != NULL) + TopScope = TopScope->getParent(); + Actions.CurScope = TopScope; + + ParsingDeclSpec SDS(*this); + SDS.SetRangeStart(Loc); + SDS.SetRangeEnd(Loc); DeclSpec::TST TagType = DeclSpec::TST_struct; DeclResult TagOrTempResult = true; bool Owned = false; @@ -500,6 +520,10 @@ Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, SDS); SDS.complete(TheDecl); Actions.ConvertDeclToDeclGroup(TheDecl); + + Actions.CurScope = SavedScope; + Actions.CurContext = SavedContext; + Actions.FunctionScopes.push_back(SavedFSI); } Decl* Parser::Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name){ @@ -565,7 +589,6 @@ DeclGroupPtrTy returnDecl = DeclGroupPtrTy(); SourceLocation Loc = Tok.getLocation(); - Create__CbC_envStruct(Loc, AS_none); ParsingDeclSpec PDS(*this); setTST(&PDS, DeclSpec::TST___code); ParsingDeclarator D(*this, PDS, static_cast<Declarator::TheContext>(Declarator::FileContext)); @@ -658,21 +681,8 @@ if(innerR.isUsable()) FnStmts.push_back(innerR.release()); - Token Next,ljTok; - Next.setKind(tok::l_paren); - ExternalSpace::StatementFilterCCC CCCValidator(Next); - CXXScopeSpec SS; - IdentifierInfo *ljName = CreateIdentifierInfo("longjmp", Loc); - Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, ljName, Loc, Next, false, &CCCValidator); - ljTok.startToken(); - ljTok.setLocation(Loc); - ljTok.setIdentifierInfo(ljName); - ljTok.setKind(tok::annot_primary_expr); - setExprAnnotation(ljTok, Classification.getExpression()); - ljTok.setAnnotationEndLoc(Loc); - PP.AnnotateCachedTokens(ljTok); ExprResult ljExpr,ljLHS; - ljExpr = getExprAnnotation(ljTok); + ljExpr = IIToExpr(CreateIdentifierInfo("longjmp", Loc), tok::l_paren); ExprVector ljArgExprs; DeclSpec ljDS(AttrFactory); setTST(&ljDS, DeclSpec::TST_struct, structName); @@ -715,6 +725,37 @@ return false; } +/* Create ExprResult from IdentifierInfo. + * It is used when II is a not primary expression such as not primary types, a function's name, etc. + */ +ExprResult Parser::IIToExpr(IdentifierInfo *II, tok::TokenKind Kind){ + SourceLocation Loc = Tok.getLocation(); + Token Next,IITok; + Next.setKind(Kind); + ExternalSpace::StatementFilterCCC CCCValidator(Next); + CXXScopeSpec SS; + Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, II, Loc, Next, false, &CCCValidator); + IITok.startToken(); + IITok.setLocation(Loc); + IITok.setIdentifierInfo(II); + IITok.setKind(tok::annot_primary_expr); + setExprAnnotation(IITok, Classification.getExpression()); + IITok.setAnnotationEndLoc(Loc); + PP.AnnotateCachedTokens(IITok); + return getExprAnnotation(IITok); +} + +StmtResult Parser::CreateComplexStmtRet(IdentifierInfo *II, bool IsAddressOfOperand){ + ExprResult ER; + if (IsAddressOfOperand) { + ER = LookupAndDeclareName(II, true); + ER = Actions.ActOnUnaryOp(getCurScope(), Tok.getLocation(), tok::amp, ER.get()); + } + else + ER = IIToExpr(II,tok::semi); + return Actions.ActOnExprStmt(ER); +} + ParmVarDecl* Parser::CreateParam(IdentifierInfo *II, int pointerNum, DeclSpec::TST T){ SourceLocation Loc = Tok.getLocation(); DeclSpec DS(AttrFactory);
--- a/tools/clang/lib/Parse/ParseExpr.cpp Thu Jan 23 23:14:57 2014 +0900 +++ b/tools/clang/lib/Parse/ParseExpr.cpp Sun Feb 02 16:01:05 2014 +0900 @@ -1277,6 +1277,14 @@ Res = ParseObjCMessageExpression(); break; } +#ifndef noCbC + case tok::kw___return: + Res = Prepare__retForGotoWithTheEnvExpr(); + break; + case tok::kw___environment: + Res = Prepare__envForGotoWithTheEnvExpr(); + break; +#endif // FALL THROUGH. default: NotCastExpr = true; @@ -2427,34 +2435,11 @@ Expr = ParseBraceInitializer(); } #ifndef noCbC - else if (Tok.is(tok::kw___return) || Tok.is(tok::kw___environment)){ - bool isKw__env = Tok.is(tok::kw___environment); - IdentifierInfo *II; - if (!preparedGotoWithTheEnv) { - if (PrepareForGotoWithTheEnv()) { // when some errors occured , go to inner statement. - return true; - } - preparedGotoWithTheEnv = true; - } - else - preparedGotoWithTheEnv = false; - - if (isKw__env) - II = CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Tok.getLocation()); - else - II = CreateIdentifierInfo(__CBC_RETURN_NAME, Tok.getLocation()); - - SourceLocation ILoc = ConsumeToken(); - UnqualifiedId Name; - Name.setIdentifier(II, ILoc); - CXXScopeSpec SS; - SourceLocation TemplateKWLoc; - CastExpressionIdValidator Validator(false, true); - Expr = ParsePostfixExpressionSuffix(Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, - Tok.is(tok::l_paren), isKw__env, &Validator)); - if (isKw__env) - Expr = Actions.ActOnUnaryOp(getCurScope(), ILoc, tok::amp, Expr.get()); - Expr = ParseRHSOfBinaryExpression(Expr, prec::Assignment); + else if (Tok.is(tok::kw___return)){ + Expr = Prepare__retForGotoWithTheEnvExpr(); + } + else if (Tok.is(tok::kw___environment)){ + Expr = Prepare__envForGotoWithTheEnvExpr(); } #endif else
--- a/tools/clang/lib/Parse/Parser.cpp Thu Jan 23 23:14:57 2014 +0900 +++ b/tools/clang/lib/Parse/Parser.cpp Sun Feb 02 16:01:05 2014 +0900 @@ -60,10 +60,6 @@ ParenCount = BracketCount = BraceCount = 0; CurParsedObjCImpl = 0; -#ifndef noCbC - preparedGotoWithTheEnv = false; -#endif - // Add #pragma handlers. These are removed and destroyed in the // destructor. AlignHandler.reset(new PragmaAlignHandler());