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());