diff tools/clang/lib/Parse/ParseCbC.cpp @ 56:bdef5c940791

copy the previous function's return type to return value
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Thu, 23 Jan 2014 23:14:57 +0900
parents d48478628b39
children 88b0e1f890d7
line wrap: on
line diff
--- a/tools/clang/lib/Parse/ParseCbC.cpp	Sun Jan 19 02:53:05 2014 +0900
+++ b/tools/clang/lib/Parse/ParseCbC.cpp	Thu Jan 23 23:14:57 2014 +0900
@@ -101,18 +101,20 @@
   bool hasArrow(unsigned F) { return F & HasArrow; }
 
   enum DeclarationFlags {
-    ArrayType   = 0x01,
-    PointerType    = 0x02,
-    FunctionType  = 0x04
+    ArrayType     = 0x01,
+    PointerType   = 0x02,
+    CbCReturnFunc  = 0x04,
+    CopyParentType = 0x08
   };
   
   bool isArray(unsigned F) { return F & ArrayType; }
   bool isPointer(unsigned F) { return F & PointerType; }
-  bool isFunction(unsigned F) { return F & FunctionType; }
+  bool isCbCRetFunc(unsigned F) { return F & CbCReturnFunc; }
+  bool shouldCopyParentsType(unsigned F) { return F & CopyParentType; }
 }
 
 
-void Parser::PrepareForGotoWithTheEnv(){
+bool Parser::PrepareForGotoWithTheEnv(){
   StmtResult Res;
   SourceLocation Loc = Tok.getLocation();
 
@@ -126,8 +128,12 @@
   ret_pII = CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc);
   retcsII = CreateUniqueIdentifierInfo(__CBC_RET_CODE_BASE_NAME, Loc);
 
-  CreateRetFunction();
-  Res = CreateDeclStmt(structII, CbCSpace::FunctionType, DeclSpec::TST___code);
+  if (CreateRetFunction()) { // error check : function type is void or not.
+    Diag(Tok, diag::err_cannot_use_goto_with_env);
+    return true;
+  }
+    
+  Res = CreateDeclStmt(__CbC_retII, CbCSpace::CbCReturnFunc, DeclSpec::TST___code);
   if (Res.isUsable())
     Stmtsp->push_back(Res.release());
 
@@ -135,11 +141,11 @@
   if (Res.isUsable())
     Stmtsp->push_back(Res.release());
 
-  Res = CreateDeclStmt(bufII, CbCSpace::ArrayType, DeclSpec::TST_int);
+  Res = CreateDeclStmt(bufII, 0, DeclSpec::TST_typename, CreateIdentifierInfo("jmp_buf", Loc));
   if (Res.isUsable())
     Stmtsp->push_back(Res.release());
 
-  Res = CreateDeclStmt(retvalII, 0, DeclSpec::TST_int);
+  Res = CreateDeclStmt(retvalII, CbCSpace::CopyParentType);
   if (Res.isUsable())
     Stmtsp->push_back(Res.release());
 
@@ -158,6 +164,7 @@
   Res = CreateAssignmentStmt(__CbC_retII, retcsII);
   if (Res.isUsable())
     Stmtsp->push_back(Res.release());
+  return false;
 }
 
 
@@ -199,8 +206,7 @@
   return Actions.ActOnExprStmt(Expr);
 }
 
-
-StmtResult Parser::CreateDeclStmt(IdentifierInfo *II, unsigned DeclFlags, DeclSpec::TST valueType, IdentifierInfo* Name){
+StmtResult Parser::CreateDeclStmt(IdentifierInfo *II, unsigned DeclFlags, DeclSpec::TST valueType, IdentifierInfo* Name, const char* size){
   SourceLocation Loc = Tok.getLocation();
   DeclGroupPtrTy DeclGPT;
   ParsingDeclSpec DS(*this);
@@ -211,16 +217,13 @@
   ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Declarator::BlockContext));
   D.SetIdentifier(II, Loc);
     
-  if (CbCSpace::isFunction(DeclFlags)) {
+  if (CbCSpace::isCbCRetFunc(DeclFlags)) {
     D.setEllipsisLoc(SourceLocation());
     bool hadGroupingParens = D.hasGroupingParens();
     D.setGroupingParens(true);
-    IdentifierInfo* II = CreateIdentifierInfo(__CBC_RETURN_NAME, 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());
@@ -241,6 +244,20 @@
     ExprResult NoexceptExpr;
     ParsedAttributes FnAttrs(AttrFactory);
     TypeResult TrailingReturnType;
+
+    ParmVarDecl *Param;
+    FunctionDecl *CurFunctionDecl = Actions.getCurFunctionDecl();
+    QualType CurFuncResQT = CurFunctionDecl->getResultType();
+    TypeSourceInfo *CurFuncTI = Actions.Context.CreateTypeSourceInfo(CurFuncResQT);
+    
+    Param = CreateParam();
+    Param->setTypeSourceInfo(CurFuncTI);
+    Param->setType(CurFuncResQT);
+    ParamInfo.push_back(DeclaratorChunk::ParamInfo(0, Loc, Param, 0));
+    Param = CreateParam(0, 1, DeclSpec::TST_void);
+    ParamInfo.push_back(DeclaratorChunk::ParamInfo(0, Loc, Param, 0));
+    HasProto = true;
+    
     D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,false,Loc,ParamInfo.data(),
 					       ParamInfo.size(),EllipsisLoc, Loc, FPDS.getTypeQualifiers(),
 					       RefQualifierIsLValueRef,RefQualifierLoc, ConstQualifierLoc,
@@ -253,22 +270,92 @@
     DSp = &FDS;
   }
   if (CbCSpace::isArray(DeclFlags))
-    CreateArrayDecl(D, Loc);
+    CreateArrayDecl(D, Loc, size);
   
   SmallVector<Decl *, 8> DeclsInGroup;
-  Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
+  Decl *FirstDecl;
+  
+  if (CbCSpace::shouldCopyParentsType(DeclFlags))
+    FirstDecl = HandleDeclAndChangeDeclType(D);
+  else
+    FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
+  
   D.complete(FirstDecl);
   DeclsInGroup.push_back(FirstDecl);
   DeclGPT =  Actions.FinalizeDeclaratorGroup(getCurScope(), *DSp, DeclsInGroup);
   return Actions.ActOnDeclStmt(DeclGPT, Loc, Loc);
 }
 
-void Parser::CreateArrayDecl(ParsingDeclarator &D, SourceLocation Loc){
+/*
+ * This function imitated Parser::ParseDeclarationAfterDeclaratorAndAttributes() and Sema::ActOnDeclarator().
+ * The origins get Type from Declarator but this function get Type from current function.
+ * It is useful for CbC to create statements for the continuation with the environments.
+ */
+Decl* Parser::HandleDeclAndChangeDeclType(Declarator &D) {
+  D.setFunctionDefinitionKind(FDK_Declaration);
+  DeclarationNameInfo NameInfo = Actions.GetNameForDeclarator(D);
+  DeclContext *DC = Actions.CurContext;
+  QualType R = Actions.getCurFunctionDecl()->getResultType();
+  TypeSourceInfo *TInfo = Actions.Context.CreateTypeSourceInfo(R);
+  Scope *S = getCurScope();
+  LookupResult Previous(Actions, NameInfo, Actions.LookupOrdinaryName, Actions.ForRedeclaration);
+  bool IsLinkageLookup = false;
+  bool CreateBuiltins = false;
+  
+  // If the declaration we're planning to build will be a function
+  // or object with linkage, then look for another declaration with
+  // linkage (C99 6.2.2p4-5 and C++ [basic.link]p6).
+  //
+  // If the declaration we're planning to build will be declared with
+  // external linkage in the translation unit, create any builtin with
+  // the same name.
+  if (R->isFunctionType()) {
+    IsLinkageLookup = true;
+    CreateBuiltins =
+      Actions.CurContext->getEnclosingNamespaceContext()->isTranslationUnit();
+  } else if (Actions.CurContext->getRedeclContext()->isTranslationUnit())
+    CreateBuiltins = true;
+  
+  if (IsLinkageLookup)
+    Previous.clear(Actions.LookupRedeclarationWithLinkage);
+  
+  Actions.LookupName(Previous, S, CreateBuiltins);
+
+  // In C++, the previous declaration we find might be a tag type
+  // (class or enum). In this case, the new declaration will hide the
+  // tag type. Note that this does does not apply if we're declaring a
+  // typedef (C++ [dcl.typedef]p4).
+  if (Previous.isSingleTagDecl())
+    Previous.clear();
+  NamedDecl *New;
+  bool AddToScope = true;
+  if (R->isFunctionType()) {
+    New = Actions.ActOnFunctionDeclarator(S, D, DC, TInfo, Previous,
+				  MultiTemplateParamsArg(), AddToScope);
+  } else {
+    New = Actions.ActOnVariableDeclarator(S, D, DC, TInfo, Previous,
+					  MultiTemplateParamsArg(), AddToScope);
+  }
+  
+  if (New->getDeclName() && AddToScope) {
+    // Only make a locally-scoped extern declaration visible if it is the first
+    // declaration of this entity. Qualified lookup for such an entity should
+    // only find this declaration if there is no visible declaration of it.
+    bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl();
+    Actions.PushOnScopeChains(New, S, AddToContext);
+    if (!AddToContext)
+      Actions.CurContext->addHiddenDecl(New);
+  }
+  
+  return New;
+}
+
+void Parser::CreateArrayDecl(ParsingDeclarator &D, SourceLocation Loc, const char* size){
   ExprResult ExprRes;
   ParsedAttributesWithRange attrs(AttrFactory);
   SmallString<128> SpellingBuffer;
-  SpellingBuffer.resize(strlen(__JMP_BUF_SIZE) + 1);
-  StringRef TokSpelling = StringRef(__JMP_BUF_SIZE, strlen(__JMP_BUF_SIZE));
+  SpellingBuffer.resize(strlen(size) + 1);
+  StringRef TokSpelling = StringRef(size, strlen(size));
   NumericLiteralParser Literal(TokSpelling, Loc, PP);
   Expr *sizeRes;
   QualType Ty;
@@ -313,30 +400,7 @@
   StmtVector innerStmts;
   StmtResult innerStmtRes;
   ExprResult innerExprRes;
-  DeclSpec CastDS(AttrFactory);
-						      
-  setTST(&CastDS, DeclSpec::TST_int);
-  Declarator CastDeclaratorInfo(CastDS, Declarator::TypeNameContext);
-  CastDeclaratorInfo.SetRangeEnd(Loc);
-  DeclSpec pointerDS(AttrFactory);
-  pointerDS.Finish(Diags, PP);
-  DeclaratorScopeObj DeclScopeObj(*this, CastDeclaratorInfo.getCXXScopeSpec());
-  CastDeclaratorInfo.SetIdentifier(0, Loc);
-  CastDeclaratorInfo.AddTypeInfo(DeclaratorChunk::getPointer(pointerDS.getTypeQualifiers(), Loc, 
-							     pointerDS.getConstSpecLoc(), 
-							     pointerDS.getVolatileSpecLoc(),
-							     pointerDS.getRestrictSpecLoc()),
-				 pointerDS.getAttributes(),SourceLocation());
-
-  innerExprRes = LookupAndDeclareName(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc));
-  innerExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc), innerExprRes.take(), false);
-  Expr *CastExpr = innerExprRes.take();
-  TypeSourceInfo *castTInfo = Actions.GetTypeForDeclaratorCast(CastDeclaratorInfo, CastExpr->getType());
-  Actions.checkUnusedDeclAttributes(CastDeclaratorInfo);
-
-  innerExprRes = Actions.BuildCStyleCastExpr(Loc, castTInfo, Loc, CastExpr);
-  innerExprRes = Actions.ActOnParenExpr(Loc, Loc, innerExprRes.take());
-  innerExprRes = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::star, innerExprRes.get());
+  innerExprRes = LookupAndDeclareName(CreateUniqueIdentifierInfo(__CBC_RETVAL_NAME, Loc));
   innerStmtRes = Actions.ActOnReturnStmt(Loc, innerExprRes.take());
   if (innerStmtRes.isUsable())
     innerStmts.push_back(innerStmtRes.release());
@@ -355,22 +419,9 @@
   CXXScopeSpec SS;
   SourceLocation TemplateKWLoc;
   ExternalSpace::CastExpressionIdValidator Validator(false,true);
+  bool IsAddressOfOperand = false;
   Name.setIdentifier(II, Loc);
-  TemplateArgumentListInfo TemplateArgsBuffer;
-  DeclarationNameInfo NameInfo;
-  const TemplateArgumentListInfo *TemplateArgs;
-  Actions.DecomposeUnqualifiedId(Name, TemplateArgsBuffer, NameInfo, TemplateArgs);
-  DeclarationName DName = NameInfo.getName();
-  II = DName.getAsIdentifierInfo();
-  SourceLocation NameLoc = NameInfo.getLoc();
-  LookupResult R(Actions, NameInfo,Actions.LookupOrdinaryName);
-  Actions.LookupParsedName(R, getCurScope(), &SS, true);
-
-  if (II && R.empty()) {
-    NamedDecl *D = Actions.ImplicitlyDefineFunction(NameLoc, *II, getCurScope());
-    if (D) R.addDecl(D);
-  }
-  return Actions.BuildDeclarationNameExpr(SS, R, false);
+  return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, false, IsAddressOfOperand, &Validator);
 }
 
 ExprResult Parser::LookupMemberAndBuildExpr(IdentifierInfo *II, Expr* Base, bool IsArrow){
@@ -495,19 +546,26 @@
   return II;
 }
 
-void Parser::CreateRetFunction(){
+bool Parser::CreateRetFunction(){
+  FunctionDecl *CurFunctionDecl = Actions.getCurFunctionDecl();
+  QualType CurFuncResQT = CurFunctionDecl->getResultType();
+  if (CurFuncResQT.getTypePtr()->isVoidType()) // this function cannot use continuation with the environment.
+    return true;
+  
   Scope *SavedScope = getCurScope();
   DeclContext *SavedContext = Actions.CurContext;
+  TypeSourceInfo *CurFuncTI = Actions.Context.CreateTypeSourceInfo(CurFuncResQT);
   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();
+  Create__CbC_envStruct(Loc, AS_none);
   ParsingDeclSpec PDS(*this);
   setTST(&PDS, DeclSpec::TST___code);
   ParsingDeclarator D(*this, PDS, static_cast<Declarator::TheContext>(Declarator::FileContext));
@@ -526,13 +584,17 @@
   ExprResult NoexceptExpr;
   ParsedAttributes FnAttrs(AttrFactory);
   TypeResult TrailingReturnType;
-		
+  ParmVarDecl *Param;
 		
   IdentifierInfo *retvalII = CreateIdentifierInfo(__CBC_RETVAL_NAME, Loc);
-  // TODO : We should change retval type to a destination function's return type. 
-  CreateParam(retvalType, retvalII, 0, &ParamInfo);
+  Param = CreateParam(retvalII);
+  Param->setTypeSourceInfo(CurFuncTI);
+  Param->setType(CurFuncResQT);
+
+  ParamInfo.push_back(DeclaratorChunk::ParamInfo(retvalII, Loc, Param, 0));
   IdentifierInfo *envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc);
-  CreateParam(DeclSpec::TST_void, envII, 1, &ParamInfo);
+  Param = CreateParam(envII, 1, DeclSpec::TST_void);
+  ParamInfo.push_back(DeclaratorChunk::ParamInfo(envII, Loc, Param, 0));
 
   D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, IsAmbiguous, Loc, ParamInfo.data(), ParamInfo.size(), EllipsisLoc, Loc,
 					     FDS.getTypeQualifiers(), RefQualifierIsLValueRef, RefQualifierLoc, ConstQualifierLoc,
@@ -553,21 +615,6 @@
   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);
@@ -576,14 +623,14 @@
 
   Declarator envDInfo(envDS, Declarator::TypeNameContext);
   envDInfo.SetRangeEnd(Loc);
-  DeclSpec starDS2(AttrFactory);
-  starDS2.Finish(Diags, PP);
+  DeclSpec starDS(AttrFactory);
+  starDS.Finish(Diags, PP);
   envDInfo.SetIdentifier(0,Loc);
-  envDInfo.AddTypeInfo(DeclaratorChunk::getPointer(starDS2.getTypeQualifiers(), Loc,
-						   starDS2.getConstSpecLoc(),
-						   starDS2.getVolatileSpecLoc(),
-						   starDS2.getRestrictSpecLoc()),
-		       starDS2.getAttributes(),
+  envDInfo.AddTypeInfo(DeclaratorChunk::getPointer(starDS.getTypeQualifiers(), Loc,
+						   starDS.getConstSpecLoc(),
+						   starDS.getVolatileSpecLoc(),
+						   starDS.getRestrictSpecLoc()),
+		       starDS.getAttributes(),
 		       SourceLocation());
   ExprVector ArgExprs2;
   LHS = LookupAndDeclareName(envII);
@@ -599,8 +646,9 @@
   LHS = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, 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);
+  DeclarationName noValDeclName;
+  TypeSourceInfo *CurFuncTypesPointerTI = Actions.Context.CreateTypeSourceInfo(Actions.BuildPointerType(CurFuncResQT, Loc, noValDeclName));
+  LHS = Actions.BuildCStyleCastExpr(Loc, CurFuncTypesPointerTI, Loc, ret_pCastExpr);
   LHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::star, LHS.get());
   ExprResult RHS;
   RHS = LookupAndDeclareName(retvalII);
@@ -631,9 +679,9 @@
 
   Declarator ljD(ljDS, Declarator::TypeNameContext);
   ljD.SetRangeEnd(Loc);
-  DeclSpec starDS3(AttrFactory);
-  starDS3.Finish(Diags, PP);
-  ljD.ExtendWithDeclSpec(starDS3);
+  DeclSpec starDS2(AttrFactory);
+  starDS2.Finish(Diags, PP);
+  ljD.ExtendWithDeclSpec(starDS2);
   ljD.SetIdentifier(0, Loc);
   ljD.AddTypeInfo(DeclaratorChunk::getPointer(ljDS.getTypeQualifiers(), Loc,
 					      ljDS.getConstSpecLoc(),
@@ -664,9 +712,10 @@
   Actions.CurScope = SavedScope;
   Actions.CurContext = SavedContext;
   Actions.FunctionScopes.push_back(SavedFSI);
+  return false;
 }
 
-void Parser::CreateParam(DeclSpec::TST T, IdentifierInfo *II, int pointerNum, SmallVector<DeclaratorChunk::ParamInfo, 16> *ParamInfo){
+ParmVarDecl* Parser::CreateParam(IdentifierInfo *II, int pointerNum, DeclSpec::TST T){
   SourceLocation Loc = Tok.getLocation();
   DeclSpec DS(AttrFactory);
   setTST(&DS, T);		
@@ -681,8 +730,8 @@
 							   pointerDS.getRestrictSpecLoc()),
 			       pointerDS.getAttributes(),SourceLocation());
   }
-  Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParamDeclarator);
-  ParamInfo->push_back(DeclaratorChunk::ParamInfo(II, ParamDeclarator.getIdentifierLoc(), Param, 0));
+  ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Actions.ActOnParamDeclarator(getCurScope(), ParamDeclarator));
+  return Param;
 
 }
 
@@ -691,11 +740,11 @@
   bool isInvalid = false;
   const char *PrevSpec = 0;
   unsigned DiagID = 0;
+  CXXScopeSpec SS;
   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;
@@ -708,6 +757,24 @@
 				       clang::TypeResult());
     isInvalid = DS->SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, TagOrTempResult.get(), Owned);
   }
+  else if (T == DeclSpec::TST_typename) {
+    Token Next,TypeTok;
+    Next.setKind(tok::identifier);
+    ExternalSpace::StatementFilterCCC CCCValidator(Next);
+    Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, Name, Loc, Next, false, &CCCValidator);
+    TypeTok.startToken();
+    TypeTok.setLocation(Loc);
+    TypeTok.setIdentifierInfo(Name);
+    TypeTok.setKind(tok::annot_typename);
+    setTypeAnnotation(TypeTok, Classification.getType());
+    TypeTok.setAnnotationEndLoc(Loc);
+    PP.AnnotateCachedTokens(TypeTok);
+    if (TypeTok.getAnnotationValue()) {
+      ParsedType PT = getTypeAnnotation(TypeTok);
+      isInvalid = DS->SetTypeSpecType(T, Loc, PrevSpec, DiagID, PT);
+    } else
+      DS->SetTypeSpecError();
+  }
   else
     isInvalid = DS->SetTypeSpecType(T, Loc, PrevSpec, DiagID);