Mercurial > hg > CbC > CbC_llvm
diff tools/clang/lib/Parse/ParseCbC.cpp @ 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 |
line wrap: on
line diff
--- 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);