changeset 48:4b59af982ef3

create return function for continuation with the environment automatically, but it can return only int value and it's name is not unique now
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Sun, 12 Jan 2014 19:15:16 +0900
parents 5b813d18f000
children c0c81d8e222e
files tools/clang/include/clang/Parse/Parser.h tools/clang/lib/Parse/ParseCbC.cpp
diffstat 2 files changed, 236 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/tools/clang/include/clang/Parse/Parser.h	Thu Jan 02 01:28:55 2014 +0900
+++ b/tools/clang/include/clang/Parse/Parser.h	Sun Jan 12 19:15:16 2014 +0900
@@ -1705,6 +1705,7 @@
 
 #ifndef noCbC
   void PrepareForGotoWithTheEnv();
+  void CreateRetFunction();
   void Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS);
   IdentifierInfo* CreateIdentifierInfo(const char* Name, int NameLen, SourceLocation Loc);
   Decl* Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name, int NameLen);
@@ -1716,6 +1717,8 @@
   void CreateArrayDecl(ParsingDeclarator &D, SourceLocation Loc);
   StmtResult CreateDeclStmt(IdentifierInfo *II = 0, unsigned DeclFlags = 0, DeclSpec::TST valueType = DeclSpec::TST_int, IdentifierInfo* Name = 0);
   IdentifierInfo* CreateSingleIdentifierInfo(const char* Name, int length, SourceLocation Loc);
+  void CreateParam(DeclSpec::TST T, IdentifierInfo *II, int pointerNum, SmallVector<DeclaratorChunk::ParamInfo, 16> *ParamInfo);
+  void setTST(DeclSpec *DS=0, DeclSpec::TST T = DeclSpec::TST_int, IdentifierInfo *Name=0);
 #endif
 
   bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
--- a/tools/clang/lib/Parse/ParseCbC.cpp	Thu Jan 02 01:28:55 2014 +0900
+++ b/tools/clang/lib/Parse/ParseCbC.cpp	Sun Jan 12 19:15:16 2014 +0900
@@ -25,6 +25,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Lex/LiteralSupport.h"
+#include "clang/AST/ASTConsumer.h"
 
 #include <cmath>
 #include <sstream>
@@ -115,6 +116,7 @@
   StmtResult Res;
   SourceLocation Loc = Tok.getLocation();
 
+  CreateRetFunction();
   Res = CreateDeclStmt(CreateIdentifierInfo(__CBC_STRUCT_NAME, __CBC_STRUCT_LENGTH, Loc), CbCSpace::FunctionType, DeclSpec::TST___code);
   if (Res.isUsable())
     Stmtsp->push_back(Res.release());
@@ -215,36 +217,7 @@
   DeclSpec *DSp;
   DSp = &DS;
 
-  DS.SetRangeStart(Loc);
-  DS.SetRangeEnd(Loc);
-
-  bool isInvalid = false;
-  const char *PrevSpec = 0;
-  unsigned DiagID = 0;
-
-  if (valueType == DeclSpec::TST_struct) {
-    ParsedAttributesWithRange attrs(AttrFactory);
-    CXXScopeSpec &SS = DS.getTypeSpecScope();
-    DeclResult TagOrTempResult = true;
-    bool Owned = false;
-    bool IsDependent = false;
-    MultiTemplateParamsArg TParams;
-    TagOrTempResult = Actions.ActOnTag(getCurScope(), valueType, Sema::TUK_Reference, Loc,
-				       SS, Name, Loc, attrs.getList(), AS_none,
-				       DS.getModulePrivateSpecLoc(),
-				       TParams, Owned, IsDependent,
-				       SourceLocation(), false,
-				       clang::TypeResult());
-    isInvalid = DS.SetTypeSpecType(valueType, Loc, Loc, PrevSpec, DiagID, TagOrTempResult.get(), Owned);
-    if (isInvalid)
-      Diag(Loc, DiagID) << PrevSpec;
-  }
-    
-  else
-    isInvalid = DS.SetTypeSpecType(valueType, Loc, PrevSpec, DiagID);
-
-  DS.SetRangeEnd(Loc);
-  DS.Finish(Diags, PP);
+  setTST(&DS, valueType, Name);
   ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Declarator::BlockContext));
   D.SetIdentifier(II, Loc);
     
@@ -352,21 +325,7 @@
   ExprResult innerExprRes;
   DeclSpec CastDS(AttrFactory);
 						      
-  if (CastDS.getSourceRange().isInvalid()) {
-    CastDS.SetRangeStart(Loc);
-    CastDS.SetRangeEnd(Loc);
-  }
-  ParsedAttributesWithRange attrs(AttrFactory);
-  bool isInvalid = false;
-  const char *PrevSpec = 0;
-  unsigned DiagID = 0;
-  isInvalid = CastDS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
-  CastDS.SetRangeEnd(Loc);
-  isInvalid = false;
-  DiagID = 0;
-  ProhibitAttributes(attrs);
-  CastDS.Finish(Diags, PP);
-
+  setTST(&CastDS, DeclSpec::TST_int);
   Declarator CastDeclaratorInfo(CastDS, Declarator::TypeNameContext);
   CastDeclaratorInfo.SetRangeEnd(Loc);
   DeclSpec pointerDS(AttrFactory);
@@ -481,7 +440,6 @@
   Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
   SmallVector<Decl *, 32> FieldDecls;
 
-  bool isInvalid = false;
   const char *PrevSpec = 0;
   unsigned DiagID = 0;
   
@@ -501,31 +459,11 @@
   Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, SDS);
   SDS.complete(TheDecl);
   Actions.ConvertDeclToDeclGroup(TheDecl);
-  if (isInvalid) {
-    assert(PrevSpec && "Method did not return previous specifier!");
-    assert(DiagID);
-    
-    if (DiagID == diag::ext_duplicate_declspec)
-      Diag(Tok, DiagID)
-	<< PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
-    else
-      Diag(Tok, DiagID) << PrevSpec;
-  }
 }
 
 Decl* Parser::Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name, int NameLen){
-  const char *PrevSpec = 0;
-  unsigned DiagID = 0;
   ParsingDeclSpec PDS(*this);
-  if (PDS.getSourceRange().isInvalid()) {
-    PDS.SetRangeStart(Loc);
-    PDS.SetRangeEnd(Loc);
-  }
-  PDS.SetTypeSpecType(T, Loc, PrevSpec, DiagID);
-  PDS.SetRangeEnd(Loc);
-      
-
-  PDS.Finish(Diags, PP);
+  setTST(&PDS, T);
   SourceLocation CommaLoc;
   ParsingFieldDeclarator DeclaratorInfo(*this, PDS);
   DeclaratorInfo.D.setCommaLoc(CommaLoc);
@@ -534,7 +472,6 @@
   DS.Finish(Diags,PP);
   DeclaratorInfo.D.SetIdentifier(CreateIdentifierInfo(Name, NameLen,Loc),Loc);
 
-
   DeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(),
 								DS.getVolatileSpecLoc(),DS.getRestrictSpecLoc()),
 				    DS.getAttributes(),SourceLocation());
@@ -545,7 +482,7 @@
   return Field;
 }
 
- IdentifierInfo* Parser::CreateIdentifierInfo(const char* Name, int NameLen, SourceLocation Loc) {
+IdentifierInfo* Parser::CreateIdentifierInfo(const char* Name, int NameLen, SourceLocation Loc) {
   Token TokenForII;
   TokenForII.startToken();
   TokenForII.setLocation(Loc);
@@ -559,5 +496,232 @@
   return II;
 }
 
+void Parser::CreateRetFunction(){
+  Scope *SavedScope = getCurScope();
+  DeclContext *SavedContext = Actions.CurContext;
+  sema::FunctionScopeInfo *SavedFSI = Actions.FunctionScopes.pop_back_val();
+  DeclSpec::TST retvalType = DeclSpec::TST_int;
+
+  Actions.CurContext = static_cast<DeclContext *>(Actions.Context.getTranslationUnitDecl());
+  Scope *TopScope = getCurScope();
+  while(TopScope->getParent() != NULL)
+    TopScope = TopScope->getParent();
+  Actions.CurScope = TopScope;
+  DeclGroupPtrTy returnDecl = DeclGroupPtrTy();
+  SourceLocation Loc = Tok.getLocation();
+  ParsingDeclSpec PDS(*this);
+  setTST(&PDS, DeclSpec::TST___code);
+  ParsingDeclarator D(*this, PDS, static_cast<Declarator::TheContext>(Declarator::FileContext));
+  D.SetIdentifier(CreateIdentifierInfo("return1", 7, Loc),Loc);
+  ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|Scope::FunctionDeclarationScope);
+  bool IsAmbiguous = false;
+  bool HasProto = true;
+  SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
+  SourceLocation EllipsisLoc, RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc;
+  DeclSpec FDS(AttrFactory);
+  bool RefQualifierIsLValueRef = true;
+  ExceptionSpecificationType ESpecType = EST_None;
+  SourceRange ESpecRange;
+  SmallVector<ParsedType, 2> DynamicExceptions;
+  SmallVector<SourceRange, 2> DynamicExceptionRanges;
+  ExprResult NoexceptExpr;
+  ParsedAttributes FnAttrs(AttrFactory);
+  TypeResult TrailingReturnType;
+		
+		
+  IdentifierInfo *retvalII = CreateIdentifierInfo(__CBC_RETVAL_NAME, __CBC_RETVAL_LENGTH, Loc);
+  // TODO : We should change retval type to a destination function's return type. 
+  CreateParam(retvalType, retvalII, 0, &ParamInfo);
+  IdentifierInfo *envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, __CBC_STRUCT_ENV_LENGTH, Loc);
+  CreateParam(DeclSpec::TST_void, envII, 1, &ParamInfo);
+
+  D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, IsAmbiguous, Loc, ParamInfo.data(), ParamInfo.size(), EllipsisLoc, Loc,
+					     FDS.getTypeQualifiers(), RefQualifierIsLValueRef, RefQualifierLoc, ConstQualifierLoc,
+					     VolatileQualifierLoc, SourceLocation(), ESpecType, ESpecRange.getBegin(),
+					     DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(),
+					     NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0,
+					     Loc, Loc, D, TrailingReturnType), FnAttrs, Loc);
+  PrototypeScope.Exit();
+	
+  Decl *TheDecl;
+  ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
+  Decl *BodyRes = Actions.ActOnStartOfFunctionDef(getCurScope(), D);
+
+  D.complete(BodyRes);
+  D.getMutableDeclSpec().abort();
+  Actions.ActOnDefaultCtorInitializers(BodyRes);
+  StmtResult FnBody;
+  StmtVector FnStmts;
+  StmtResult innerR;
+  ExprResult retvalAssginmentExpr,LHS;
+  DeclSpec retvalTypeDS(AttrFactory);
+  setTST(&retvalTypeDS, retvalType);
+  
+  Declarator retvalTypeDInfo(retvalTypeDS, Declarator::TypeNameContext);
+  retvalTypeDInfo.SetRangeEnd(Loc);
+  DeclSpec starDS(AttrFactory);
+  starDS.Finish(Diags, PP);
+  retvalTypeDInfo.SetIdentifier(0, Loc);
+  retvalTypeDInfo.AddTypeInfo(DeclaratorChunk::getPointer(starDS.getTypeQualifiers(), Loc,
+							  starDS.getConstSpecLoc(),
+							  starDS.getVolatileSpecLoc(),
+							  starDS.getRestrictSpecLoc()),
+			      starDS.getAttributes(),
+			      SourceLocation());
+				    
+  ExprVector ArgExprs;
+  CommaLocsTy CommaLocs;
+  DeclSpec envDS(AttrFactory);
+  IdentifierInfo *structName = CreateIdentifierInfo(__CBC_STRUCT_NAME, __CBC_STRUCT_LENGTH, Loc);
+  setTST(&envDS, DeclSpec::TST_struct, structName);
+
+  Declarator envDInfo(envDS, Declarator::TypeNameContext);
+  envDInfo.SetRangeEnd(Loc);
+  DeclSpec starDS2(AttrFactory);
+  starDS2.Finish(Diags, PP);
+  envDInfo.SetIdentifier(0,Loc);
+  envDInfo.AddTypeInfo(DeclaratorChunk::getPointer(starDS2.getTypeQualifiers(), Loc,
+						   starDS2.getConstSpecLoc(),
+						   starDS2.getVolatileSpecLoc(),
+						   starDS2.getRestrictSpecLoc()),
+		       starDS2.getAttributes(),
+		       SourceLocation());
+  ExprVector ArgExprs2;
+  LHS = LookupAndDeclareName(envII);
+  ArgExprs2.push_back(LHS.release());
+  LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs2);
+  Expr *envCastExpr = LHS.take();
+  TypeSourceInfo *castTInfo = Actions.GetTypeForDeclaratorCast(envDInfo, envCastExpr->getType());
+  LHS = Actions.MaybeConvertParenListExprToParenExpr(getCurScope(), envCastExpr);
+  envCastExpr = LHS.take();
+  LHS = Actions.BuildCStyleCastExpr(Loc, castTInfo, Loc, envCastExpr);
+  ArgExprs.push_back(LHS.release());	
+  LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs);
+  LHS = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, __CBC_STRUCT_POINTER_LENGTH, Loc),
+				  LHS.take(), true);
+  Expr *ret_pCastExpr = LHS.take();
+  TypeSourceInfo *castTInfo2 = Actions.GetTypeForDeclaratorCast(retvalTypeDInfo, ret_pCastExpr->getType());
+  LHS = Actions.BuildCStyleCastExpr(Loc, castTInfo2, Loc, ret_pCastExpr);
+  LHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::star, LHS.get());
+  ExprResult RHS;
+  RHS = LookupAndDeclareName(retvalII);
+			    
+  retvalAssginmentExpr = Actions.ActOnBinOp(getCurScope(), Loc, tok::equal, LHS.take(), RHS.take());
+  innerR = Actions.ActOnExprStmt(retvalAssginmentExpr);
+  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", 7, 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);
+  ExprVector ljArgExprs;
+  DeclSpec ljDS(AttrFactory);
+  setTST(&ljDS, DeclSpec::TST_struct, structName);
+
+  Declarator ljD(ljDS, Declarator::TypeNameContext);
+  ljD.SetRangeEnd(Loc);
+  DeclSpec starDS3(AttrFactory);
+  starDS3.Finish(Diags, PP);
+  ljD.ExtendWithDeclSpec(starDS3);
+  ljD.SetIdentifier(0, Loc);
+  ljD.AddTypeInfo(DeclaratorChunk::getPointer(ljDS.getTypeQualifiers(), Loc,
+					      ljDS.getConstSpecLoc(),
+					      ljDS.getVolatileSpecLoc(),
+					      ljDS.getRestrictSpecLoc()),
+		  ljDS.getAttributes(),
+		  SourceLocation());
+  ljLHS = LookupAndDeclareName(envII);
+  Expr *ljCastExpr = ljLHS.take();
+  TypeSourceInfo *ljCastTInfo = Actions.GetTypeForDeclaratorCast(ljD, ljCastExpr->getType());
+  ljLHS = Actions.BuildCStyleCastExpr(Loc, ljCastTInfo, Loc, ljCastExpr);
+  ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.take());
+  ljLHS = LookupMemberAndBuildExpr(envII, ljLHS.take(), true);
+  ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.take());
+  ljArgExprs.push_back(ljLHS.release());
+  CommaLocs.push_back(Loc);
+  ljLHS = Actions.ActOnIntegerConstant(Loc, 1 /* return value for setjmp */);
+  ljArgExprs.push_back(ljLHS.release());
+  ljExpr = Actions.ActOnCallExpr(getCurScope(), ljExpr.take(), Loc, ljArgExprs, Loc, 0);
+  innerR = Actions.ActOnExprStmt(ljExpr);
+  if(innerR.isUsable())
+    FnStmts.push_back(innerR.release());
+  FnBody = Actions.ActOnCompoundStmt(Loc, Loc, FnStmts, false);
+  BodyScope.Exit();
+  TheDecl = Actions.ActOnFinishFunctionBody(BodyRes, FnBody.take());
+  returnDecl =  Actions.ConvertDeclToDeclGroup(TheDecl);
+  (&Actions.getASTConsumer())->HandleTopLevelDecl(returnDecl.get());
+  Actions.CurScope = SavedScope;
+  Actions.CurContext = SavedContext;
+  Actions.FunctionScopes.push_back(SavedFSI);
+}
+
+void Parser::CreateParam(DeclSpec::TST T, IdentifierInfo *II, int pointerNum, SmallVector<DeclaratorChunk::ParamInfo, 16> *ParamInfo){
+  SourceLocation Loc = Tok.getLocation();
+  DeclSpec DS(AttrFactory);
+  setTST(&DS, T);		
+  Declarator ParamDeclarator(DS, Declarator::PrototypeContext);
+  ParamDeclarator.SetIdentifier(II, Loc);
+  for(int i = 0;i<pointerNum; i++){
+    DeclSpec pointerDS(AttrFactory);
+    pointerDS.Finish(Diags, PP);
+    ParamDeclarator.AddTypeInfo(DeclaratorChunk::getPointer(pointerDS.getTypeQualifiers(), Loc,
+							   pointerDS.getConstSpecLoc(),
+							   pointerDS.getVolatileSpecLoc(),
+							   pointerDS.getRestrictSpecLoc()),
+			       pointerDS.getAttributes(),SourceLocation());
+  }
+  Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParamDeclarator);
+  ParamInfo->push_back(DeclaratorChunk::ParamInfo(II, ParamDeclarator.getIdentifierLoc(), Param, 0));
+
+}
+
+void Parser::setTST(DeclSpec *DS, DeclSpec::TST T, IdentifierInfo* Name){
+  SourceLocation Loc = Tok.getLocation();
+  bool isInvalid = false;
+  const char *PrevSpec = 0;
+  unsigned DiagID = 0;
+  DS->SetRangeStart(Loc);
+  DS->SetRangeEnd(Loc);
+  if (T == DeclSpec::TST_struct) {
+    ParsedAttributesWithRange attrs(AttrFactory);
+    CXXScopeSpec &SS = DS->getTypeSpecScope();
+    DeclResult TagOrTempResult = true;
+    bool Owned = false;
+    bool IsDependent = false;
+    MultiTemplateParamsArg TParams;
+    TagOrTempResult = Actions.ActOnTag(getCurScope(), T, Sema::TUK_Reference, Loc,
+				       SS, Name, Loc, attrs.getList(), AS_none,
+				       DS->getModulePrivateSpecLoc(),
+				       TParams, Owned, IsDependent,
+				       SourceLocation(), false,
+				       clang::TypeResult());
+    isInvalid = DS->SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, TagOrTempResult.get(), Owned);
+  }
+  else
+    isInvalid = DS->SetTypeSpecType(T, Loc, PrevSpec, DiagID);
+  
+  DS->Finish(Diags, PP);
+  if (isInvalid) {
+    assert(PrevSpec && "Method did not return previous specifier!");
+    assert(DiagID);
+    if (DiagID == diag::ext_duplicate_declspec)
+      Diag(Tok, DiagID)
+	<< PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
+    else
+      Diag(Tok, DiagID) << PrevSpec;
+  }
+}
 
 #endif