changeset 45:9ebfb52ddd9b

create declaration statement automatically for __CbC_environment
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Wed, 01 Jan 2014 22:12:11 +0900
parents aabc64b7263e
children ced88226fdc5
files tools/clang/include/clang/Basic/TokenKinds.def tools/clang/include/clang/Parse/Parser.h tools/clang/lib/Parse/ParseCbC.cpp tools/clang/lib/Parse/ParseDecl.cpp tools/clang/lib/Parse/ParseExpr.cpp
diffstat 5 files changed, 274 insertions(+), 256 deletions(-) [+]
line wrap: on
line diff
--- a/tools/clang/include/clang/Basic/TokenKinds.def	Wed Jan 01 02:12:01 2014 +0900
+++ b/tools/clang/include/clang/Basic/TokenKinds.def	Wed Jan 01 22:12:11 2014 +0900
@@ -267,10 +267,10 @@
 KEYWORD(__objc_yes                  , KEYALL)
 KEYWORD(__objc_no                   , KEYALL)
 
-#ifndef noCbC
+#ifndef noCbC // CbC Keywords.
 KEYWORD(__code                      , KEYALL)
 KEYWORD(__return                    , KEYALL)
-KEYWORD(__environment                    , KEYALL)
+KEYWORD(__environment               , KEYALL)
 #endif
 
 // C++ 2.11p1: Keywords.
--- a/tools/clang/include/clang/Parse/Parser.h	Wed Jan 01 02:12:01 2014 +0900
+++ b/tools/clang/include/clang/Parse/Parser.h	Wed Jan 01 22:12:11 2014 +0900
@@ -1538,13 +1538,6 @@
   StmtResult ParseGotoStatement();
 #ifndef noCbC
   StmtResult ParseCbCGotoStatement(ParsedAttributesWithRange &Attrs,StmtVector &Stmts);
-  StmtResult Create__returnStmt();
-  StmtResult CreateSjForContinuationWithEnv();
-  StmtResult CreateAssignmentStmt(IdentifierInfo* LHSII = 0, IdentifierInfo* RHSII = 0, unsigned LHSFlags = 0,
-				  unsigned RHSFlags = 0, IdentifierInfo* extraLHSII = 0, IdentifierInfo* extraRHSII = 0);
-  void CreateArrayDecl(ParsingDeclarator &D, SourceLocation Loc);
-  StmtResult CreateDeclStmt(IdentifierInfo *II, bool isArray);
-  IdentifierInfo* CreateSingleIdentifierInfo(const char* Name, int length, SourceLocation Loc);
 #endif
   StmtResult ParseContinueStatement();
   StmtResult ParseBreakStatement();
@@ -1710,23 +1703,18 @@
   void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback);
 
 #ifndef noCbC
-  bool Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS);
+  void PrepareForContinuationWithTheEnv();
+  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, bool* isInvalid,
-			    const char* PrevSpec, unsigned* DiagID, const char* Name, int NameLen);
+  Decl* Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name, int NameLen);
   ExprResult LookupAndDeclareName(IdentifierInfo *II);
   ExprResult LookupMemberAndBuildExpr(IdentifierInfo *II, Expr* Base, bool IsArrow);
-  enum AssignmentFlags {
-    HasStar   = 0x01,
-    HasAmp    = 0x02,
-    HasPeriod = 0x04,
-    HasArrow  = 0x08
-  };
-  
-  bool hasStar(unsigned F) { return F & HasStar; }
-  bool hasAmp(unsigned F) { return F & HasAmp; }
-  bool hasPeriod(unsigned F) { return F & HasPeriod; }
-  bool hasArrow(unsigned F) { return F & HasArrow; }
+  StmtResult CreateSjForContinuationWithEnv();
+  StmtResult CreateAssignmentStmt(IdentifierInfo* LHSII = 0, IdentifierInfo* RHSII = 0, unsigned LHSFlags = 0,
+				  unsigned RHSFlags = 0, IdentifierInfo* extraLHSII = 0, IdentifierInfo* extraRHSII = 0);
+  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);
 #endif
 
   bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
--- a/tools/clang/lib/Parse/ParseCbC.cpp	Wed Jan 01 02:12:01 2014 +0900
+++ b/tools/clang/lib/Parse/ParseCbC.cpp	Wed Jan 01 22:12:11 2014 +0900
@@ -86,80 +86,75 @@
 };
 }
 
+namespace CbCSpace{
+  enum AssignmentFlags {
+    HasStar   = 0x01,
+    HasAmp    = 0x02,
+    HasPeriod = 0x04,
+    HasArrow  = 0x08
+  };
+  
+  bool hasStar(unsigned F) { return F & HasStar; }
+  bool hasAmp(unsigned F) { return F & HasAmp; }
+  bool hasPeriod(unsigned F) { return F & HasPeriod; }
+  bool hasArrow(unsigned F) { return F & HasArrow; }
 
-StmtResult Parser::Create__returnStmt(){
-  SourceLocation Loc = Tok.getLocation();
-  ParsedAttributesWithRange __retAttrs(AttrFactory);
-  ParsingDeclSpec PDS(*this);
-  DeclSpec &__retDS = PDS;
-  const char *PrevSpec = 0;
-  unsigned DiagID = 0;
-  bool isInvalid = false;
-  if (__retDS.getSourceRange().isInvalid()) {
-    __retDS.SetRangeStart(Loc);
-    __retDS.SetRangeEnd(Loc);
-  }
-  isInvalid = __retDS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec, DiagID);
-  if (isInvalid) {
-    assert(PrevSpec && "Method did not return previous specifier!");
-    assert(DiagID);
-    if (DiagID == diag::ext_duplicate_declspec)
-      Diag(Tok, DiagID)
-	<< PrevSpec << FixItHint::CreateRemoval(Loc);
-    else
-      Diag(Tok, DiagID) << PrevSpec;
-  }
-  __retDS.SetRangeEnd(Loc);
-  __retDS.Finish(Diags, PP);
-  ParsingDeclarator D(*this, PDS, static_cast<Declarator::TheContext>(Declarator::BlockContext));
-  D.setEllipsisLoc(SourceLocation());
-  bool hadGroupingParens = D.hasGroupingParens();
-  D.setGroupingParens(true);
-  IdentifierInfo* II = CreateIdentifierInfo(__CBC_RETURN_NAME, __CBC_RETURN_LENGTH, Loc);
-  D.SetRangeEnd(Loc);
-  DeclSpec DS(AttrFactory);
-
-  DS.Finish(Diags, PP);
-  D.SetIdentifier(II, Loc);
+  enum DeclarationFlags {
+    ArrayType   = 0x01,
+    PointerType    = 0x02,
+    FunctionType  = 0x04
+  };
   
-  D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(),DS.getVolatileSpecLoc(),
-					    DS.getRestrictSpecLoc()),DS.getAttributes(),SourceLocation());
-  D.setGroupingParens(hadGroupingParens);
+  bool isArray(unsigned F) { return F & ArrayType; }
+  bool isPointer(unsigned F) { return F & PointerType; }
+  bool isFunction(unsigned F) { return F & FunctionType; }
+}
+
+
+void Parser::PrepareForContinuationWithTheEnv(){
+  StmtResult Res;
+  SourceLocation Loc = Tok.getLocation();
+
+  Res = CreateDeclStmt(CreateIdentifierInfo(__CBC_STRUCT_NAME, __CBC_STRUCT_LENGTH, Loc), CbCSpace::FunctionType, DeclSpec::TST___code);
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
+
+  Res = CreateDeclStmt(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, __CBC_ENVIRONMENT_LENGTH, Loc), 0, DeclSpec::TST_struct,
+		       CreateIdentifierInfo(__CBC_STRUCT_NAME, __CBC_STRUCT_LENGTH, Loc));
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
+
+  bufII = CreateSingleIdentifierInfo(__CBC_BUF_NAME, __CBC_BUF_LENGTH, Loc);
+  Res = CreateDeclStmt(bufII, CbCSpace::ArrayType, DeclSpec::TST_int);
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
 
-  
-  ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|
-  			    (D.isFunctionDeclaratorAFunctionDeclaration() ? Scope::FunctionDeclarationScope : 0));
-  bool HasProto = false;
-  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;
-  D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,false,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();
-  
-  SmallVector<Decl *, 8> DeclsInGroup;
-  Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
-  D.complete(FirstDecl);
-  DeclsInGroup.push_back(FirstDecl);
-  
-  DeclGroupPtrTy __retDecl = Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
-  return Actions.ActOnDeclStmt(__retDecl, Loc, Loc);
+  retvalII = CreateSingleIdentifierInfo(__CBC_RETVAL_NAME, __CBC_RETVAL_LENGTH, Loc);
+  Res = CreateDeclStmt(retvalII, 0, DeclSpec::TST_int);
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
+
+  Res = CreateAssignmentStmt(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, __CBC_ENVIRONMENT_LENGTH, Loc),
+			     retvalII, CbCSpace::HasPeriod, CbCSpace::HasAmp, CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, __CBC_STRUCT_POINTER_LENGTH, Loc));
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
+
+  Res = CreateAssignmentStmt(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, __CBC_ENVIRONMENT_LENGTH, Loc),
+			     bufII, CbCSpace::HasPeriod, 0, CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, __CBC_STRUCT_ENV_LENGTH, Loc));
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
+
+  Res = CreateSjForContinuationWithEnv();
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
+      
+  Res = CreateAssignmentStmt(CreateIdentifierInfo(__CBC_RETURN_NAME, __CBC_RETURN_LENGTH, Loc),
+			     CreateIdentifierInfo("return1", 7, Loc));
+  if (Res.isUsable())
+    Stmtsp->push_back(Res.release());
 }
 
+
 StmtResult Parser::CreateAssignmentStmt(IdentifierInfo* LHSII,IdentifierInfo* RHSII,unsigned LHSFlags,unsigned RHSFlags,
 					IdentifierInfo* extraLHSII,IdentifierInfo* extraRHSII){
   ExprResult Expr,LHS,RHS;
@@ -181,16 +176,16 @@
   
   LHS = getExprAnnotation(LHSToken);
 
-  if ( hasPeriod(LHSFlags) ) 
+  if ( CbCSpace::hasPeriod(LHSFlags) ) 
     LHS = LookupMemberAndBuildExpr(extraLHSII, LHS.take(), false);
-  else if ( hasArrow(LHSFlags) ) 
+  else if ( CbCSpace::hasArrow(LHSFlags) ) 
     LHS = LookupMemberAndBuildExpr(extraLHSII, LHS.take(), true); // It is not sure.
   
   RHS = LookupAndDeclareName(RHSII);
-  if ( hasAmp(RHSFlags) )
+  if ( CbCSpace::hasAmp(RHSFlags) )
     RHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::amp, RHS.get());
 
-  else if ( hasStar(RHSFlags) )
+  else if ( CbCSpace::hasStar(RHSFlags) )
     RHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::star, RHS.get()); // It is not sure.
 
   Expr = Actions.ActOnBinOp(getCurScope(), Loc,tok::equal,LHS.take(),RHS.take());
@@ -213,34 +208,95 @@
   }
 }
 
-StmtResult Parser::CreateDeclStmt(IdentifierInfo *II, bool isArray){
+StmtResult Parser::CreateDeclStmt(IdentifierInfo *II, unsigned DeclFlags, DeclSpec::TST valueType, IdentifierInfo* Name){
   SourceLocation Loc = Tok.getLocation();
   DeclGroupPtrTy DeclGPT;
   ParsingDeclSpec DS(*this);
-    
-  if (DS.getSourceRange().isInvalid()) {
-    DS.SetRangeStart(Loc);
-    DS.SetRangeEnd(Loc);
-  }
+  DeclSpec *DSp;
+  DSp = &DS;
+
+  DS.SetRangeStart(Loc);
+  DS.SetRangeEnd(Loc);
 
   bool isInvalid = false;
   const char *PrevSpec = 0;
   unsigned DiagID = 0;
-  isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
+
+  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);
   ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Declarator::BlockContext));
-  DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
   D.SetIdentifier(II, Loc);
     
-  if(isArray)
+  if (CbCSpace::isFunction(DeclFlags)) {
+    D.setEllipsisLoc(SourceLocation());
+    bool hadGroupingParens = D.hasGroupingParens();
+    D.setGroupingParens(true);
+    IdentifierInfo* II = CreateIdentifierInfo(__CBC_RETURN_NAME, __CBC_RETURN_LENGTH, Loc);
+    D.SetRangeEnd(Loc);
+    DeclSpec FDS(AttrFactory);
+    
+    DS.Finish(Diags, PP);
+    D.SetIdentifier(II, Loc);
+    
+    D.AddTypeInfo(DeclaratorChunk::getPointer(FDS.getTypeQualifiers(), Loc, FDS.getConstSpecLoc(), FDS.getVolatileSpecLoc(),
+					      FDS.getRestrictSpecLoc()), FDS.getAttributes(), SourceLocation());
+    D.setGroupingParens(hadGroupingParens);
+    
+    
+    ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|
+			      (D.isFunctionDeclaratorAFunctionDeclaration() ? Scope::FunctionDeclarationScope : 0));
+    bool HasProto = false;
+    SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
+    SourceLocation EllipsisLoc, RefQualifierLoc, ConstQualifierLoc, VolatileQualifierLoc;
+    DeclSpec FPDS(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;
+    D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,false,Loc,ParamInfo.data(),
+					       ParamInfo.size(),EllipsisLoc, Loc, FPDS.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();
+    DSp = &FDS;
+  }
+  if (CbCSpace::isArray(DeclFlags))
     CreateArrayDecl(D, Loc);
-
+  
   SmallVector<Decl *, 8> DeclsInGroup;
   Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
   D.complete(FirstDecl);
   DeclsInGroup.push_back(FirstDecl);
-  DeclGPT =  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
+  DeclGPT =  Actions.FinalizeDeclaratorGroup(getCurScope(), *DSp, DeclsInGroup);
   return Actions.ActOnDeclStmt(DeclGPT, Loc, Loc);
 }
 
@@ -278,7 +334,7 @@
   ExprResult __envExprRes = CondExp.get();
 
   __envExprRes = LookupAndDeclareName(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, __CBC_ENVIRONMENT_LENGTH, Loc));
-  __envExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo("env", 3, Loc), __envExprRes.take(), false);
+  __envExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, __CBC_STRUCT_ENV_LENGTH,Loc), __envExprRes.take(), false);
 
   ArgExprs.push_back(__envExprRes.release());
   CondExp = Actions.ActOnCallExpr(getCurScope(), CondExp.take(), Loc, ArgExprs, Loc, 0);
@@ -324,7 +380,7 @@
 				 pointerDS.getAttributes(),SourceLocation());
 
   innerExprRes = LookupAndDeclareName(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, __CBC_ENVIRONMENT_LENGTH, Loc));
-  innerExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo("ret_p",5,Loc), innerExprRes.take(), false);
+  innerExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME,__CBC_STRUCT_POINTER_LENGTH,Loc), innerExprRes.take(), false);
   Expr *CastExpr = innerExprRes.take();
   TypeSourceInfo *castTInfo = Actions.GetTypeForDeclaratorCast(CastDeclaratorInfo, CastExpr->getType());
   Actions.checkUnusedDeclAttributes(CastDeclaratorInfo);
@@ -389,4 +445,119 @@
   return Actions.BuildMemberReferenceExpr(Base, Base->getType(), Loc, IsArrow, SS, TemplateKWLoc, 0, R, TemplateArgs,false, &ExtraArgs);
 
 }
+
+
+/// 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, __CBC_STRUCT_LENGTH, 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;
+  
+
+  DeclSpec::TST TagType = DeclSpec::TST_struct;
+  DeclResult TagOrTempResult = true;
+  bool Owned = false;
+  bool IsDependent = false;
+  ParsedAttributesWithRange attrs(AttrFactory);
+  MultiTemplateParamsArg TParams;
+      
+  TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, Sema::TUK_Definition, Loc,
+				     SDS.getTypeSpecScope(), Name, Loc, attrs.getList(), AS,
+				     SDS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
+				     SourceLocation(), false, clang::TypeResult());
+
+  Decl *TagDecl = TagOrTempResult.get();
+  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, Loc, "parsing struct/union body");
+  ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
+  Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
+  SmallVector<Decl *, 32> FieldDecls;
+
+  bool isInvalid = false;
+  const char *PrevSpec = 0;
+  unsigned DiagID = 0;
+  
+  FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, __CBC_STRUCT_POINTER_NAME, __CBC_STRUCT_POINTER_LENGTH));
+  FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_int, Loc, __CBC_STRUCT_ENV_NAME, __CBC_STRUCT_ENV_LENGTH));
+
+  Actions.ActOnFields(getCurScope(),Loc, TagDecl, FieldDecls,Loc, Loc,attrs.getList());
+  StructScope.Exit();
+  Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,Loc);
+  bool Result = SDS.SetTypeSpecType(TagType, Loc,Loc.isValid() ? Loc : Loc, PrevSpec, DiagID, TagOrTempResult.get(), Owned);
+
+  if (Result){
+    Diag(Loc, DiagID) << PrevSpec;
+  }
+
+  SDS.Finish(Diags,PP);
+  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);
+  SourceLocation CommaLoc;
+  ParsingFieldDeclarator DeclaratorInfo(*this, PDS);
+  DeclaratorInfo.D.setCommaLoc(CommaLoc);
+  DeclaratorInfo.D.SetRangeEnd(Loc);
+  DeclSpec DS(AttrFactory);
+  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());
+  Decl *Field = Actions.ActOnField(getCurScope(), TagDecl,
+				   DeclaratorInfo.D.getDeclSpec().getSourceRange().getBegin(),
+				   DeclaratorInfo.D, DeclaratorInfo.BitfieldSize);
+  DeclaratorInfo.complete(Field);
+  return Field;
+}
+
+ IdentifierInfo* Parser::CreateIdentifierInfo(const char* Name, int NameLen, SourceLocation Loc) {
+  Token TokenForII;
+  TokenForII.startToken();
+  TokenForII.setLocation(Loc);
+  TokenForII.setLength(NameLen);
+  TokenForII.setKind(tok::raw_identifier);
+  TokenForII.setRawIdentifierData(Name);
+  IdentifierInfo *II;
+  II = PP.getIdentifierInfo(StringRef(TokenForII.getRawIdentifierData(),TokenForII.getLength()));
+  TokenForII.setIdentifierInfo(II);
+  TokenForII.setKind(II->getTokenID());
+  return II;
+}
+
+
 #endif
--- a/tools/clang/lib/Parse/ParseDecl.cpp	Wed Jan 01 02:12:01 2014 +0900
+++ b/tools/clang/lib/Parse/ParseDecl.cpp	Wed Jan 01 22:12:11 2014 +0900
@@ -3119,10 +3119,8 @@
       break;
 #ifndef noCbC
     case tok::kw___code: {
-      // create __CbC_env
-      bool isInvalid__CbC_env = false;
       if (getCurScope()->getParent() == NULL) // If the current scope has parent scope, it is not the glabal scope.
-	isInvalid__CbC_env = Create__CbC_envStruct(Loc,AS);
+	Create__CbC_envStruct(Loc,AS);
 
       if (DS.getSourceRange().isInvalid()) {
 	DS.SetRangeStart(Tok.getLocation());
@@ -3131,7 +3129,7 @@
       LangOptions* LOP;
       LOP = const_cast<LangOptions*>(&getLangOpts());
       LOP->HasCodeSegment = 1;
-      isInvalid = (DS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec, DiagID) || isInvalid__CbC_env);
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec, DiagID);
       break;
     }
 #endif
@@ -5952,109 +5950,3 @@
   }
   return false;
 }
-
-#ifndef noCbC
-
-/// 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 and just return "false".
-bool 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_env", /* length of the name */ 9, 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 false;
-  
-  // start ParseClassSpecifier 
-  DeclSpec::TST TagType = DeclSpec::TST_struct;
-  DeclResult TagOrTempResult = true; // invalid
-  bool Owned = false;
-  bool IsDependent = false;
-  ParsedAttributesWithRange attrs(AttrFactory);
-  MultiTemplateParamsArg TParams;
-      
-  TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, Sema::TUK_Definition, Loc,
-				     SDS.getTypeSpecScope(), Name, Loc, attrs.getList(), AS,
-				     SDS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
-				     SourceLocation(), false, clang::TypeResult());
-  // start ParseStructUnionBody
-  Decl *TagDecl = TagOrTempResult.get();
-  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, Loc, "parsing struct/union body");
-  ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
-  Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
-  SmallVector<Decl *, 32> FieldDecls;
-
-  bool isInvalid = false;
-  const char *PrevSpec = 0;
-  unsigned DiagID = 0;
-  
-  // create struct body (void* ret_p, int* env)
-  FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, &isInvalid, PrevSpec, &DiagID, "ret_p", /* length of the name */ 5));
-  FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_int, Loc, &isInvalid, PrevSpec, &DiagID, "env", /* length of the name */ 3));
-
-  Actions.ActOnFields(getCurScope(),Loc, TagDecl, FieldDecls,Loc, Loc,attrs.getList());
-  StructScope.Exit();
-  Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,Loc);
-  bool Result;
-  Result = SDS.SetTypeSpecType(TagType, Loc,Loc.isValid() ? Loc : Loc, PrevSpec, DiagID, TagOrTempResult.get(), Owned);
-  if (Result){
-    Diag(Loc, DiagID) << PrevSpec;
-  }
-  SDS.Finish(Diags,PP);
-  Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, SDS);
-  SDS.complete(TheDecl);
-  Actions.ConvertDeclToDeclGroup(TheDecl);
-  return isInvalid;
-}
-
-Decl* Parser::Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, bool* isInvalid,
-				  const char* PrevSpec, unsigned* DiagID, const char* Name, int NameLen){
-  ParsingDeclSpec PDS(*this);
-  if (PDS.getSourceRange().isInvalid()) {
-    PDS.SetRangeStart(Loc);
-    PDS.SetRangeEnd(Loc);
-  }
-  *isInvalid = (PDS.SetTypeSpecType(T, Loc, PrevSpec, *DiagID) || *isInvalid);
-  PDS.SetRangeEnd(Loc);
-      
-  // star(*)
-  PDS.Finish(Diags, PP);
-  SourceLocation CommaLoc;
-  ParsingFieldDeclarator DeclaratorInfo(*this, PDS);
-  DeclaratorInfo.D.setCommaLoc(CommaLoc);
-  DeclaratorInfo.D.SetRangeEnd(Loc);
-  DeclSpec DS(AttrFactory);
-  DS.Finish(Diags,PP);
-  DeclaratorInfo.D.SetIdentifier(CreateIdentifierInfo(Name, NameLen,Loc),Loc);
-  // end of check star(*)
-
-  DeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(),
-								DS.getVolatileSpecLoc(),DS.getRestrictSpecLoc()),
-				    DS.getAttributes(),SourceLocation());
-  Decl *Field = Actions.ActOnField(getCurScope(), TagDecl,
-				   DeclaratorInfo.D.getDeclSpec().getSourceRange().getBegin(),
-				   DeclaratorInfo.D, DeclaratorInfo.BitfieldSize);
-  DeclaratorInfo.complete(Field);
-  return Field;
-}
-
- IdentifierInfo* Parser::CreateIdentifierInfo(const char* Name, int NameLen, SourceLocation Loc) {
-  Token TokenForII;
-  TokenForII.startToken();
-  TokenForII.setLocation(Loc);
-  TokenForII.setLength(NameLen);
-  TokenForII.setKind(tok::raw_identifier);
-  TokenForII.setRawIdentifierData(Name);
-  IdentifierInfo *II;
-  II = PP.getIdentifierInfo(StringRef(TokenForII.getRawIdentifierData(),TokenForII.getLength()));
-  TokenForII.setIdentifierInfo(II);
-  TokenForII.setKind(II->getTokenID());
-  return II;
-}
-
-#endif
--- a/tools/clang/lib/Parse/ParseExpr.cpp	Wed Jan 01 02:12:01 2014 +0900
+++ b/tools/clang/lib/Parse/ParseExpr.cpp	Wed Jan 01 22:12:11 2014 +0900
@@ -2428,51 +2428,18 @@
     } 
 #ifndef noCbC
     else if (Tok.is(tok::kw___return)){
-      StmtResult Res;
-      SourceLocation Loc = Tok.getLocation();
       IdentifierInfo *II;
-      Res = Create__returnStmt();
-      if (Res.isUsable())
-      	Stmtsp->push_back(Res.release());
-
-      bufII = CreateSingleIdentifierInfo(__CBC_BUF_NAME, __CBC_BUF_LENGTH, Loc);
-      Res = CreateDeclStmt(bufII, true);
-      if (Res.isUsable())
-      	Stmtsp->push_back(Res.release());
-
-      retvalII = CreateSingleIdentifierInfo(__CBC_RETVAL_NAME, __CBC_RETVAL_LENGTH, Loc);
-      Res = CreateDeclStmt(retvalII, false);
-      if (Res.isUsable())
-      	Stmtsp->push_back(Res.release());
-
-      Res = CreateAssignmentStmt(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, __CBC_ENVIRONMENT_LENGTH, Loc),
-				 retvalII, HasPeriod, HasAmp, CreateIdentifierInfo("ret_p", 5, Loc));
-      if (Res.isUsable())
-      	Stmtsp->push_back(Res.release());
-
-      Res = CreateAssignmentStmt(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, __CBC_ENVIRONMENT_LENGTH, Loc),
-				 bufII, HasPeriod, 0, CreateIdentifierInfo("env", 3, Loc));
-      if (Res.isUsable())
-      	Stmtsp->push_back(Res.release());
-
-      Res = CreateSjForContinuationWithEnv();
-      if (Res.isUsable())
-	Stmtsp->push_back(Res.release());
-      
-      Res = CreateAssignmentStmt(CreateIdentifierInfo(__CBC_RETURN_NAME, __CBC_RETURN_LENGTH, Loc),
-					    CreateIdentifierInfo("return1", 7, Loc));
-      if (Res.isUsable())
-      	Stmtsp->push_back(Res.release());
-      
+      PrepareForContinuationWithTheEnv();
       II = CreateIdentifierInfo(__CBC_RETURN_NAME, __CBC_RETURN_LENGTH, Tok.getLocation());
       SourceLocation ILoc = ConsumeToken();
       UnqualifiedId Name;
       Name.setIdentifier(II, ILoc);
-      CXXScopeSpec ScopeSpec;
+      CXXScopeSpec SS;
       SourceLocation TemplateKWLoc;
 
       CastExpressionIdValidator Validator(false, true);
-      Expr = ParseRHSOfBinaryExpression(ParsePostfixExpressionSuffix(Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren), /* isAddressOfOperand = */false, &Validator)),prec::Assignment);
+      Expr = ParseRHSOfBinaryExpression(ParsePostfixExpressionSuffix(Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name,
+											       Tok.is(tok::l_paren), false, &Validator)),prec::Assignment);
       
     }
 #endif