changeset 28:273f76252412

create __CbC_env automatically when input file contains code segment
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Sun, 08 Dec 2013 00:16:12 +0900
parents ecf2394747e1
children 00b59dd660f7
files tools/clang/include/clang/Parse/Parser.h tools/clang/lib/Parse/ParseDecl.cpp
diffstat 2 files changed, 155 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/tools/clang/include/clang/Parse/Parser.h	Tue Nov 12 20:27:46 2013 +0900
+++ b/tools/clang/include/clang/Parse/Parser.h	Sun Dec 08 00:16:12 2013 +0900
@@ -1660,6 +1660,10 @@
 
   void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback);
 
+#ifndef noCbC
+  bool Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS);
+#endif
+
   bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
   bool isTypeSpecifierQualifier();
   bool isTypeQualifier() const;
--- a/tools/clang/lib/Parse/ParseDecl.cpp	Tue Nov 12 20:27:46 2013 +0900
+++ b/tools/clang/lib/Parse/ParseDecl.cpp	Sun Dec 08 00:16:12 2013 +0900
@@ -2876,11 +2876,17 @@
       break;
 #ifndef noCbC
     case tok::kw___code: {
+      //start of creating __CbC_env
+      bool isInvalid__CbC_env = Create__CbC_envStruct(Loc,AS);
+      //end of creating __CbC_env
+      if (DS.getSourceRange().isInvalid()) {
+	DS.SetRangeStart(Tok.getLocation());
+	DS.SetRangeEnd(Tok.getLocation());
+      }
       LangOptions* LOP;
       LOP = const_cast<LangOptions*>(&getLangOpts());
       LOP->HasCodeSegment = 1;
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec,
-				     DiagID);
+      isInvalid = (DS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec, DiagID) || isInvalid__CbC_env);
       break;
     }
 #endif
@@ -5655,3 +5661,146 @@
   }
   return false;
 }
+
+#ifndef noCbC
+bool Parser::Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS) {
+  ParsingDeclSpec SDS(*this);
+  if (SDS.getSourceRange().isInvalid()) {
+    SDS.SetRangeStart(Loc);
+    SDS.SetRangeEnd(Loc);
+  }
+  Token identifierToken;
+  identifierToken.startToken();
+  const char *CbC_envId = "__CbC_env";
+  identifierToken.setLength(9); //length of __CbC_env
+  identifierToken.setKind(tok::raw_identifier);
+  identifierToken.setRawIdentifierData(CbC_envId);
+  IdentifierInfo *Name;
+  Name = PP.getIdentifierInfo(StringRef(identifierToken.getRawIdentifierData(),identifierToken.getLength()));
+  identifierToken.setIdentifierInfo(Name);
+  identifierToken.setKind(Name->getTokenID());
+      
+  // 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;
+  ParsingDeclSpec ret_pPDS(*this);
+      
+  if (ret_pPDS.getSourceRange().isInvalid()) {
+    ret_pPDS.SetRangeStart(Loc);
+    ret_pPDS.SetRangeEnd(Loc);
+  }
+  bool isInvalid = false;
+  const char *PrevSpec = 0;
+  unsigned DiagID = 0;
+  isInvalid = ret_pPDS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
+					DiagID);
+  ret_pPDS.SetRangeEnd(Loc);
+      
+  // ここまでで void読み込んだ。 PreSpeとDiagIDは未使用。
+  // TokenKindがstar(*)になる。
+  ret_pPDS.Finish(Diags, PP); //これは consumeTokenでTokenがstarになったあとのもの。
+      
+  ret_pPDS.getParsedSpecifiers(); 
+  SourceLocation CommaLoc;
+  ParsingFieldDeclarator ret_pDeclaratorInfo(*this, ret_pPDS);
+  ret_pDeclaratorInfo.D.setCommaLoc(CommaLoc);
+  ColonProtectionRAIIObject ret_pX(*this);
+  Token ret_pToken;
+  ret_pToken.startToken();
+  const char *ret_pId = "ret_p";
+  ret_pToken.setLength(5); //length of ret_p
+  ret_pToken.setKind(tok::raw_identifier);
+  ret_pToken.setRawIdentifierData(ret_pId);
+  IdentifierInfo *II;
+  II = PP.getIdentifierInfo(StringRef(ret_pToken.getRawIdentifierData(),ret_pToken.getLength()));
+  ret_pToken.setIdentifierInfo(II);
+  ret_pToken.setKind(II->getTokenID());
+  ret_pDeclaratorInfo.D.SetRangeEnd(Loc);
+  DeclSpec ret_pDS(AttrFactory);
+  ret_pDS.Finish(Diags,PP);
+  ret_pDeclaratorInfo.D.SetIdentifier(II,Loc);
+  // ここでConsumeToken()が入る。Kindはsemi(;)に。
+  ret_pDeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(ret_pDS.getTypeQualifiers(), Loc,ret_pDS.getConstSpecLoc(),
+								ret_pDS.getVolatileSpecLoc(),ret_pDS.getRestrictSpecLoc()),
+				    ret_pDS.getAttributes(),SourceLocation());
+  Decl *Field = Actions.ActOnField(getCurScope(), TagDecl,
+				   ret_pDeclaratorInfo.D.getDeclSpec().getSourceRange().getBegin(),
+				   ret_pDeclaratorInfo.D, ret_pDeclaratorInfo.BitfieldSize);
+  FieldDecls.push_back(Field);
+  ret_pDeclaratorInfo.complete(Field);
+  // こっからjmp_buf(intのポインタ)の作成。
+  ParsingDeclSpec jmp_bufPDS(*this);
+      
+  if (jmp_bufPDS.getSourceRange().isInvalid()) {
+    jmp_bufPDS.SetRangeStart(Loc);
+    jmp_bufPDS.SetRangeEnd(Loc);
+  }
+  DiagID = 0;
+  isInvalid = (jmp_bufPDS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID) || isInvalid);
+  jmp_bufPDS.SetRangeEnd(Loc);
+  jmp_bufPDS.Finish(Diags, PP);
+  jmp_bufPDS.getParsedSpecifiers();
+  CommaLoc = SourceLocation();
+  ParsingFieldDeclarator jmp_bufDeclaratorInfo(*this, jmp_bufPDS);
+  jmp_bufDeclaratorInfo.D.setCommaLoc(CommaLoc);
+  ColonProtectionRAIIObject env_pX(*this);
+  jmp_bufDeclaratorInfo.D.SetRangeEnd(Loc);
+  Token envToken;
+  envToken.startToken();
+  const char *env_pId = "env";
+  envToken.setLength(3); //length of env
+  envToken.setKind(tok::raw_identifier);
+  envToken.setRawIdentifierData(env_pId);
+  II = PP.getIdentifierInfo(StringRef(envToken.getRawIdentifierData(),envToken.getLength()));
+  envToken.setIdentifierInfo(II);
+  envToken.setKind(II->getTokenID());
+  jmp_bufDeclaratorInfo.D.SetRangeEnd(Loc);
+  DeclSpec jmp_bufDS(AttrFactory);
+  jmp_bufDS.Finish(Diags,PP);
+  jmp_bufDeclaratorInfo.D.SetIdentifier(II,Loc);
+  // ここでConsumeToken()が入る。Kindはsemi(;)に。
+  jmp_bufDeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(jmp_bufDS.getTypeQualifiers(), Loc,jmp_bufDS.getConstSpecLoc(),
+								  jmp_bufDS.getVolatileSpecLoc(),jmp_bufDS.getRestrictSpecLoc()),
+				      jmp_bufDS.getAttributes(),SourceLocation());
+  Field = Actions.ActOnField(getCurScope(), TagDecl,
+			     jmp_bufDeclaratorInfo.D.getDeclSpec().getSourceRange().getBegin(),
+			     jmp_bufDeclaratorInfo.D, jmp_bufDeclaratorInfo.BitfieldSize);
+  FieldDecls.push_back(Field);
+  jmp_bufDeclaratorInfo.complete(Field);
+  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;
+}
+#endif