Mercurial > hg > CbC > CbC_llvm
changeset 89:9020ffd06b8b
Create prototype declaration automatically (only support direct continuation)
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 14 Apr 2015 03:55:39 +0900 |
parents | e471d82fb99b |
children | 2ddce554fef0 |
files | tools/clang/.git/index tools/clang/include/clang/Lex/Preprocessor.h tools/clang/include/clang/Parse/Parser.h tools/clang/lib/Lex/PPDirectives.cpp tools/clang/lib/Parse/ParseCbC.cpp tools/clang/lib/Parse/ParseDecl.cpp tools/clang/lib/Parse/ParseStmt.cpp |
diffstat | 7 files changed, 86 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/tools/clang/include/clang/Lex/Preprocessor.h Mon Apr 13 18:34:22 2015 +0900 +++ b/tools/clang/include/clang/Lex/Preprocessor.h Tue Apr 14 03:55:39 2015 +0900 @@ -1615,6 +1615,8 @@ unsigned int SavedDepth; Token SavedToken; bool SavedTokenFlag; + void ClearCache(); + void RestoreTokens(Token *Toks, unsigned NumToks); #endif };
--- a/tools/clang/include/clang/Parse/Parser.h Mon Apr 13 18:34:22 2015 +0900 +++ b/tools/clang/include/clang/Parse/Parser.h Tue Apr 14 03:55:39 2015 +0900 @@ -1570,6 +1570,7 @@ StmtVector* Stmtsp; const char* curFuncName; unsigned int UniqueId; + bool ProtoParsing = false; #endif StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr); StmtResult @@ -1804,6 +1805,7 @@ ExprResult Prepare__envForGotoWithTheEnvExpr(); bool isVoidFunction(); bool SearchCodeSegmentDeclaration(std::string Name); + void CreatePrototypeDeclaration(Token IITok); #endif bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
--- a/tools/clang/lib/Lex/PPDirectives.cpp Mon Apr 13 18:34:22 2015 +0900 +++ b/tools/clang/lib/Lex/PPDirectives.cpp Tue Apr 14 03:55:39 2015 +0900 @@ -2560,4 +2560,14 @@ EnterSourceFile(FID, CurDir, FilenameTok.getLocation()); return true; } + +void Preprocessor::ClearCache(){ + CachedTokens.clear(); + CachedLexPos = 0; +} + +void Preprocessor::RestoreTokens(Token *Toks, unsigned NumToks){ + EnterCachingLexMode(); + CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Toks, Toks + NumToks); +} #endif
--- a/tools/clang/lib/Parse/ParseCbC.cpp Mon Apr 13 18:34:22 2015 +0900 +++ b/tools/clang/lib/Parse/ParseCbC.cpp Tue Apr 14 03:55:39 2015 +0900 @@ -931,9 +931,51 @@ /// If we can't find it , return false; bool Parser::SearchCodeSegmentDeclaration(std::string Name){ while(SkipUntil(tok::kw___code,StopBeforeMatch)){ - if(NextToken().getIdentifierInfo()->getName().str() == Name) + if(NextToken().is(tok::identifier) && NextToken().getIdentifierInfo()->getName().str() == Name) return true; + ConsumeToken(); } return false; } + +/// CreatePrototypeDeclaration - Create prototype declaration by it's definition. +void Parser::CreatePrototypeDeclaration(Token IITok){ + // move to the top level scope + Scope *SavedScope = getCurScope(); + DeclContext *SavedContext = Actions.CurContext; + sema::FunctionScopeInfo *SavedFSI = Actions.FunctionScopes.pop_back_val(); + Actions.CurContext = static_cast<DeclContext *>(Actions.Context.getTranslationUnitDecl()); + Scope *TopScope = getCurScope(); + while(TopScope->getParent() != NULL) + TopScope = TopScope->getParent(); + Actions.CurScope = TopScope; + + Token CachedTokens[] = {IITok, PP.LookAhead(1)}; + Token SavedToken = Tok; + PP.ClearCache(); + ProtoParsing = true; + + StringRef Filename; + Filename = StringRef("proto.h",7); + const DirectoryLookup *CurDir; + FileID FID = PP.getSourceManager().createFileID(PP.getCurrentFileLexer()->getFileEntry(), IITok.getLocation(), SrcMgr::C_User); + PP.EnterSourceFile(FID,CurDir,IITok.getLocation()); + ConsumeToken(); + SearchCodeSegmentDeclaration(IITok.getIdentifierInfo()->getName().str()); + + // move to the previous scope. + DeclGroupPtrTy ProtoDecl; + ParseTopLevelDecl(ProtoDecl); + (&Actions.getASTConsumer())->HandleTopLevelDecl(ProtoDecl.get()); + Actions.CurScope = SavedScope; + Actions.CurContext = SavedContext; + Actions.FunctionScopes.push_back(SavedFSI); + + // recover tokens + Tok = SavedToken; + PP.RestoreTokens(CachedTokens, 2); + + ProtoParsing = false; +} + #endif
--- a/tools/clang/lib/Parse/ParseDecl.cpp Mon Apr 13 18:34:22 2015 +0900 +++ b/tools/clang/lib/Parse/ParseDecl.cpp Tue Apr 14 03:55:39 2015 +0900 @@ -1668,6 +1668,9 @@ // Check to see if we have a function *definition* which must have a body. if (D.isFunctionDeclarator() && +#ifndef noCbC + !ProtoParsing && +#endif // Look at the next token to make sure that this isn't a function // declaration. We have to check this because __attribute__ might be the // start of a function definition in GCC-extended K&R C. @@ -1747,6 +1750,10 @@ DeclsInGroup.push_back(FirstDecl); bool ExpectSemi = Context != Declarator::ForContext; + +#ifndef noCbC + ExpectSemi = ExpectSemi && !ProtoParsing; +#endif // If we don't have a comma, it is either the end of the list (a ';') or an // error, bail out. @@ -1804,6 +1811,12 @@ } } +#ifndef noCbC + if(ProtoParsing){ + Token T; + PP.HandleEndOfFile(T, false); + } +#endif return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); }
--- a/tools/clang/lib/Parse/ParseStmt.cpp Mon Apr 13 18:34:22 2015 +0900 +++ b/tools/clang/lib/Parse/ParseStmt.cpp Tue Apr 14 03:55:39 2015 +0900 @@ -27,6 +27,8 @@ #ifndef noCbC #include "clang/Sema/Lookup.h" +#include "clang/Basic/SourceManager.h" +#include "clang/AST/ASTConsumer.h" #endif using namespace clang; @@ -253,20 +255,23 @@ case tok::kw_goto: // C99 6.8.6.1: goto-statement #ifndef noCbC - if (!(NextToken().is(tok::identifier) && PP.LookAhead(1).is(tok::semi)) && // C: 'goto' identifier ';' - NextToken().isNot(tok::star)) { // C: 'goto' '*' expression ';' - SemiError = "goto code segment"; - - if(NextToken().is(tok::identifier)){ // Probably, direct continuation. goto csName(); - LookupResult LR(Actions, NextToken().getIdentifierInfo(), NextToken().getLocation(), Actions.LookupOrdinaryName); - CXXScopeSpec SS; - Actions.LookupParsedName(LR, getCurScope(), &SS, !(Actions.getCurMethodDecl())); - if(LR.getResultKind() == LookupResult::NotFound){ + { + Token Next = NextToken(); + if (!(Next.is(tok::identifier) && PP.LookAhead(1).is(tok::semi)) && // C: 'goto' identifier ';' + Next.isNot(tok::star)) { // C: 'goto' '*' expression ';' + SemiError = "goto code segment"; + if(Next.is(tok::identifier)){ // Probably, direct continuation. goto csName(); + LookupResult LR(Actions, Next.getIdentifierInfo(), Next.getLocation(), Actions.LookupOrdinaryName); + CXXScopeSpec SS; + Actions.LookupParsedName(LR, getCurScope(), &SS, !(Actions.getCurMethodDecl())); + if(LR.getResultKind() == LookupResult::NotFound){ + CreatePrototypeDeclaration(Next); + } + } + return ParseCbCGotoStatement(Attrs, Stmts); // CbC: goto codesegment statement } - - return ParseCbCGotoStatement(Attrs, Stmts); // CbC: goto codesegment statement } #endif Res = ParseGotoStatement();