changeset 36:2b67512dc318

Add key word '__return'. If the source code declarates the __return , we emit a code segment for continuation with the environment (this code segment's identifier is __CbC_return). TODO: change code segment name to '__CbC_return' automatically when we use a continuation with the environment.
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Sat, 14 Dec 2013 18:22:46 +0900
parents 503e14e069e4
children e9d31d41d9f7
files tools/clang/include/clang/Basic/TokenKinds.def tools/clang/include/clang/Parse/Parser.h tools/clang/lib/AST/ASTContext.cpp tools/clang/lib/Parse/ParseDecl.cpp tools/clang/lib/Parse/Parser.cpp
diffstat 5 files changed, 143 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/tools/clang/include/clang/Basic/TokenKinds.def	Thu Dec 12 23:38:21 2013 +0900
+++ b/tools/clang/include/clang/Basic/TokenKinds.def	Sat Dec 14 18:22:46 2013 +0900
@@ -269,6 +269,7 @@
 
 #ifndef noCbC
 KEYWORD(__code                      , KEYALL)
+KEYWORD(__return                    , KEYALL)
 #endif
 
 // C++ 2.11p1: Keywords.
--- a/tools/clang/include/clang/Parse/Parser.h	Thu Dec 12 23:38:21 2013 +0900
+++ b/tools/clang/include/clang/Parse/Parser.h	Sat Dec 14 18:22:46 2013 +0900
@@ -1668,7 +1668,13 @@
                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
                                   AccessSpecifier AS = AS_none,
                                   DeclSpecContext DSC = DSC_normal,
-                                  LateParsedAttrList *LateAttrs = 0);
+                                  LateParsedAttrList *LateAttrs = 0
+#ifndef noCbC
+				  ,bool *isCbC_envKw = 0,
+				  unsigned Context = 0,
+				  DeclGroupPtrTy* retDecl = 0
+#endif
+				  );
   bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
                                              DeclSpecContext DSContext,
                                              LateParsedAttrList *LateAttrs = 0);
@@ -1699,7 +1705,7 @@
 
 #ifndef noCbC
   bool Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS);
-  IdentifierInfo* CreateIdentifierInfo(const char* Name, int NameLen);
+  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);
 #endif
--- a/tools/clang/lib/AST/ASTContext.cpp	Thu Dec 12 23:38:21 2013 +0900
+++ b/tools/clang/lib/AST/ASTContext.cpp	Sat Dec 14 18:22:46 2013 +0900
@@ -5141,6 +5141,9 @@
                                             BuiltinType::Kind kind) {
     switch (kind) {
     case BuiltinType::Void:       return 'v';
+#ifndef noCbC
+    case BuiltinType::__Code:     return 'v';
+#endif
     case BuiltinType::Bool:       return 'B';
     case BuiltinType::Char_U:
     case BuiltinType::UChar:      return 'C';
--- a/tools/clang/lib/Parse/ParseDecl.cpp	Thu Dec 12 23:38:21 2013 +0900
+++ b/tools/clang/lib/Parse/ParseDecl.cpp	Sat Dec 14 18:22:46 2013 +0900
@@ -1493,7 +1493,16 @@
   ParsingDeclSpec DS(*this);
 
   DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
+#ifndef noCbC
+  bool isCbC_envKw = false;
+  DeclGroupPtrTy retDecl;
+  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext, 0, &isCbC_envKw, Context, &retDecl);
+  if(isCbC_envKw){
+    return retDecl;
+  }
+#else
   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext);
+#endif
 
   // If we had a free-standing type definition with a missing semicolon, we
   // may get this far before the problem becomes obvious.
@@ -2558,7 +2567,13 @@
                                         const ParsedTemplateInfo &TemplateInfo,
                                         AccessSpecifier AS,
                                         DeclSpecContext DSContext,
-                                        LateParsedAttrList *LateAttrs) {
+                                        LateParsedAttrList *LateAttrs
+#ifndef noCbC
+				        ,bool *isCbC_envKw,
+				        unsigned Context,
+					DeclGroupPtrTy* retDecl
+#endif
+					) {
   if (DS.getSourceRange().isInvalid()) {
     DS.SetRangeStart(Tok.getLocation());
     DS.SetRangeEnd(Tok.getLocation());
@@ -3134,6 +3149,95 @@
       isInvalid = (DS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec, DiagID) || isInvalid__CbC_env);
       break;
     }
+    case tok::kw___return: {
+      *isCbC_envKw = true;
+      ParsingDeclSpec PDS(*this);
+      DeclSpec &__retDS = PDS;
+      if (__retDS.getSourceRange().isInvalid()) {
+	__retDS.SetRangeStart(Tok.getLocation());
+	__retDS.SetRangeEnd(Tok.getLocation());
+      }
+      // ^ for init ParsingDeclSpec
+
+      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(Tok.getLocation());
+	else
+	  Diag(Tok, DiagID) << PrevSpec;
+      }
+      __retDS.SetRangeEnd(Tok.getLocation());
+      // ConsumeToken()によりTokenがl_parenに                                                                                 
+      __retDS.Finish(Diags, PP);
+      // ParseDeclarationSpecifiersを抜ける。
+      if(getCurScope()->isClassScope()){ //in the struct or the union.
+	
+      } else {
+	ParsingDeclarator D(*this, PDS, static_cast<Declarator::TheContext>(Context));
+	//	ParsedAttributes attrs(AttrFactory);
+	//	SourceLocation EllipsisLoc = D.getEllipsisLoc();
+	D.setEllipsisLoc(SourceLocation());
+	bool hadGroupingParens = D.hasGroupingParens();
+	D.setGroupingParens(true);
+	IdentifierInfo* II = CreateIdentifierInfo("__CbC_return",12, Loc); // CreateIdentifierInfo(name,length of the name, SourceLocation);
+	D.SetRangeEnd(Loc);
+	DeclSpec DS_(AttrFactory);
+	// ->ParseTypeQualifierListOpt                                                                                          
+	DS_.Finish(Diags, PP);
+	D.SetIdentifier(II, Loc);	// ParseDeclaratorInternal<-                                                                                            
+	D.AddTypeInfo(DeclaratorChunk::getPointer(DS_.getTypeQualifiers(), Loc,DS_.getConstSpecLoc(),DS_.getVolatileSpecLoc(),
+						  DS_.getRestrictSpecLoc()),DS_.getAttributes(),SourceLocation());
+	D.setGroupingParens(hadGroupingParens);
+	// ParseDirectDeclarator<-                                                                                              
+
+	ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|
+				  (D.isFunctionDeclaratorAFunctionDeclaration() ? Scope::FunctionDeclarationScope : 0));
+	bool HasProto = false;
+	SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
+	SourceLocation EllipsisLoc;
+	DeclSpec DS__(AttrFactory);
+	bool RefQualifierIsLValueRef = true;
+	SourceLocation RefQualifierLoc;
+	SourceLocation ConstQualifierLoc;
+	SourceLocation VolatileQualifierLoc;
+	ExceptionSpecificationType ESpecType = EST_None;
+	SourceRange ESpecRange;
+	SmallVector<ParsedType, 2> DynamicExceptions;
+	SmallVector<SourceRange, 2> DynamicExceptionRanges;
+	ExprResult NoexceptExpr;
+	ParsedAttributes FnAttrs(AttrFactory);
+	TypeResult TrailingReturnType;
+	Actions.ActOnStartFunctionDeclarator();
+	Actions.ActOnEndFunctionDeclarator();
+	D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,false,Loc,ParamInfo.data(),
+						   ParamInfo.size(),EllipsisLoc, Loc,DS__.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();
+	// ParseDeclGroup<-ParseDeclarator<-ParseDeclaratorInternal<-ParseDirectDeclarator<-                                                            
+
+	SmallVector<Decl *, 8> DeclsInGroup;
+	Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
+	D.complete(FirstDecl);
+	DeclsInGroup.push_back(FirstDecl);
+
+	*retDecl = Actions.FinalizeDeclaratorGroup(getCurScope(), DS_, DeclsInGroup);
+	// ParseSimpleDeclaration<-                                                                                                                     
+	ConsumeToken();// eat __return
+	ConsumeToken();// eat semi
+
+	return;
+      }
+      break;
+    }
 #endif
     case tok::kw_char:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
@@ -4086,6 +4190,7 @@
   case tok::kw_void:
 #ifndef noCbC
   case tok::kw___code:
+  case tok::kw___return:
 #endif
   case tok::kw_char:
   case tok::kw_wchar_t:
@@ -4329,6 +4434,7 @@
   case tok::kw_void:
 #ifndef noCbC
   case tok::kw___code:
+  case tok::kw___return:
 #endif
   case tok::kw_char:
   case tok::kw_wchar_t:
@@ -5890,6 +5996,7 @@
   case tok::kw___pixel:
 #ifndef noCbC
   case tok::kw___code:
+  case tok::kw___return:
 #endif
     Tok.setKind(tok::kw___vector);
     return true;
@@ -5925,6 +6032,7 @@
     case tok::kw___pixel:
 #ifndef noCbC
   case tok::kw___code:
+  case tok::kw___return:
 #endif
       isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
       return true;
@@ -5963,7 +6071,7 @@
     SDS.SetRangeStart(Loc);
     SDS.SetRangeEnd(Loc);
   }
-  IdentifierInfo *Name = CreateIdentifierInfo("__CbC_env", /* length of the name */ 9);;
+  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);
@@ -6030,7 +6138,7 @@
   DeclaratorInfo.D.SetRangeEnd(Loc);
   DeclSpec DS(AttrFactory);
   DS.Finish(Diags,PP);
-  DeclaratorInfo.D.SetIdentifier(CreateIdentifierInfo(Name, NameLen),Loc);
+  DeclaratorInfo.D.SetIdentifier(CreateIdentifierInfo(Name, NameLen,Loc),Loc);
   // end of check star(*)
 
   DeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(),
@@ -6043,16 +6151,25 @@
   return Field;
 }
 
-IdentifierInfo* Parser::CreateIdentifierInfo(const char* Name, int NameLen) {
+ 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());
+  /*
+  if(Tok.getKind() == tok::kw___return){
+    TokenForII.setKind(tok::identifier);
+    //    II->setTokenID(tok::identifier);
+  }
+  else
+  */
+    TokenForII.setKind(II->getTokenID());
+  
   return II;
 }
 
--- a/tools/clang/lib/Parse/Parser.cpp	Thu Dec 12 23:38:21 2013 +0900
+++ b/tools/clang/lib/Parse/Parser.cpp	Sat Dec 14 18:22:46 2013 +0900
@@ -887,7 +887,16 @@
                                        ParsingDeclSpec &DS,
                                        AccessSpecifier AS) {
   // Parse the common declaration-specifiers piece.
+#ifndef noCbC
+  bool isCbC_envKw = false;
+  DeclGroupPtrTy retDecl;
+  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSC_top_level, 0, &isCbC_envKw, Declarator::FileContext, &retDecl);
+  if(isCbC_envKw){
+    return retDecl;
+  }
+#else
   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
+#endif
 
   // If we had a free-standing type definition with a missing semicolon, we
   // may get this far before the problem becomes obvious.