Mercurial > hg > CbC > CbC_llvm
view 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 source
#ifndef noCbC #include "clang/Parse/Parser.h" #include "RAIIObjectsForParser.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" #include "clang/Sema/TypoCorrection.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/ADT/SmallString.h" #include "clang/Sema/Lookup.h" #include "clang/Lex/LiteralSupport.h" #include "clang/AST/ASTConsumer.h" #include <cmath> #include <sstream> #include <string> #include "CbCHelper.h" using namespace clang; namespace ExternalSpace { // from ParseExpr.cpp , ParseStmt.cpp class CastExpressionIdValidator : public CorrectionCandidateCallback { public: CastExpressionIdValidator(bool AllowTypes, bool AllowNonTypes) : AllowNonTypes(AllowNonTypes) { WantTypeSpecifiers = AllowTypes; } virtual bool ValidateCandidate(const TypoCorrection &candidate) { NamedDecl *ND = candidate.getCorrectionDecl(); if (!ND) return candidate.isKeyword(); if (isa<TypeDecl>(ND)) return WantTypeSpecifiers; return AllowNonTypes; } private: bool AllowNonTypes; }; class StatementFilterCCC : public CorrectionCandidateCallback { public: StatementFilterCCC(Token nextTok) : NextToken(nextTok) { WantTypeSpecifiers = nextTok.is(tok::l_paren) || nextTok.is(tok::less) || nextTok.is(tok::identifier) || nextTok.is(tok::star) || nextTok.is(tok::amp) || nextTok.is(tok::l_square); WantExpressionKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::identifier) || nextTok.is(tok::arrow) || nextTok.is(tok::period); WantRemainingKeywords = nextTok.is(tok::l_paren) || nextTok.is(tok::semi) || nextTok.is(tok::identifier) || nextTok.is(tok::l_brace); WantCXXNamedCasts = false; } virtual bool ValidateCandidate(const TypoCorrection &candidate) { if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>()) return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD); if (NextToken.is(tok::equal)) return candidate.getCorrectionDeclAs<VarDecl>(); if (NextToken.is(tok::period) && candidate.getCorrectionDeclAs<NamespaceDecl>()) return false; return CorrectionCandidateCallback::ValidateCandidate(candidate); } private: Token NextToken; }; } 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; } enum DeclarationFlags { ArrayType = 0x01, PointerType = 0x02, CbCReturnFunc = 0x04, CopyParentType = 0x08 }; bool isArray(unsigned F) { return F & ArrayType; } bool isPointer(unsigned F) { return F & PointerType; } bool isCbCRetFunc(unsigned F) { return F & CbCReturnFunc; } bool shouldCopyParentsType(unsigned F) { return F & CopyParentType; } } bool Parser::PrepareForGotoWithTheEnv(){ StmtResult Res; SourceLocation Loc = Tok.getLocation(); IdentifierInfo *bufII, *retvalII, *structII, *__CbC_envII, *__CbC_retII,*envII, *ret_pII, *retcsII; bufII = CreateUniqueIdentifierInfo(__CBC_BUF_NAME, Loc); retvalII = CreateUniqueIdentifierInfo(__CBC_RETVAL_NAME, Loc); structII = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc); __CbC_envII = CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc); __CbC_retII = CreateIdentifierInfo(__CBC_RETURN_NAME, Loc); envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc); ret_pII = CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc); retcsII = CreateUniqueIdentifierInfo(__CBC_RET_CODE_BASE_NAME, Loc); 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()); Res = CreateDeclStmt(__CbC_envII, 0, DeclSpec::TST_struct, structII); if (Res.isUsable()) Stmtsp->push_back(Res.release()); Res = CreateDeclStmt(bufII, 0, DeclSpec::TST_typename, CreateIdentifierInfo("jmp_buf", Loc)); if (Res.isUsable()) Stmtsp->push_back(Res.release()); Res = CreateDeclStmt(retvalII, CbCSpace::CopyParentType); if (Res.isUsable()) Stmtsp->push_back(Res.release()); Res = CreateAssignmentStmt(__CbC_envII, retvalII, CbCSpace::HasPeriod, CbCSpace::HasAmp, ret_pII); if (Res.isUsable()) Stmtsp->push_back(Res.release()); Res = CreateAssignmentStmt(__CbC_envII, bufII, CbCSpace::HasPeriod, 0, envII); if (Res.isUsable()) Stmtsp->push_back(Res.release()); Res = CreateSjForContinuationWithEnv(); if (Res.isUsable()) Stmtsp->push_back(Res.release()); Res = CreateAssignmentStmt(__CbC_retII, retcsII); if (Res.isUsable()) Stmtsp->push_back(Res.release()); return false; } StmtResult Parser::CreateAssignmentStmt(IdentifierInfo* LHSII,IdentifierInfo* RHSII,unsigned LHSFlags,unsigned RHSFlags, IdentifierInfo* extraLHSII,IdentifierInfo* extraRHSII){ ExprResult Expr,LHS,RHS; Token Next,LHSToken; SourceLocation Loc = Tok.getLocation(); CXXScopeSpec SS; Next.startToken(); Next.setKind(tok::period); LHSToken.startToken(); LHSToken.setLocation(Loc); LHSToken.setIdentifierInfo(LHSII); LHSToken.setKind(tok::annot_primary_expr); ExternalSpace::StatementFilterCCC Validator(Next); Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, LHSII, Loc, Next, false, SS.isEmpty() ? &Validator : 0); setExprAnnotation(LHSToken, Classification.getExpression()); LHSToken.setAnnotationEndLoc(Loc); PP.AnnotateCachedTokens(LHSToken); LHS = getExprAnnotation(LHSToken); if ( CbCSpace::hasPeriod(LHSFlags) ) LHS = LookupMemberAndBuildExpr(extraLHSII, LHS.take(), false); else if ( CbCSpace::hasArrow(LHSFlags) ) LHS = LookupMemberAndBuildExpr(extraLHSII, LHS.take(), true); // It is not sure. RHS = LookupAndDeclareName(RHSII); if ( CbCSpace::hasAmp(RHSFlags) ) RHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::amp, RHS.get()); 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()); return Actions.ActOnExprStmt(Expr); } StmtResult Parser::CreateDeclStmt(IdentifierInfo *II, unsigned DeclFlags, DeclSpec::TST valueType, IdentifierInfo* Name, const char* size){ SourceLocation Loc = Tok.getLocation(); DeclGroupPtrTy DeclGPT; ParsingDeclSpec DS(*this); DeclSpec *DSp; DSp = &DS; setTST(&DS, valueType, Name); ParsingDeclarator D(*this, DS, static_cast<Declarator::TheContext>(Declarator::BlockContext)); D.SetIdentifier(II, Loc); if (CbCSpace::isCbCRetFunc(DeclFlags)) { D.setEllipsisLoc(SourceLocation()); bool hadGroupingParens = D.hasGroupingParens(); D.setGroupingParens(true); D.SetRangeEnd(Loc); DeclSpec FDS(AttrFactory); DS.Finish(Diags, PP); 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; 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, 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, size); SmallVector<Decl *, 8> DeclsInGroup; 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); } /* * 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(size) + 1); StringRef TokSpelling = StringRef(size, strlen(size)); NumericLiteralParser Literal(TokSpelling, Loc, PP); Expr *sizeRes; QualType Ty; unsigned MaxWidth = Actions.Context.getTargetInfo().getIntMaxTWidth(); llvm::APInt ResultVal(MaxWidth, 0); Literal.GetIntegerValue(ResultVal); unsigned Width = 0; unsigned IntSize = Actions.Context.getTargetInfo().getIntWidth(); Ty = Actions.Context.IntTy; Width = IntSize; ResultVal = ResultVal.trunc(Width); sizeRes = IntegerLiteral::Create(Actions.Context, ResultVal, Ty, Loc); ExprRes = Actions.Owned(sizeRes); D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,ExprRes.release(),Loc,Loc),attrs,Loc); } StmtResult Parser::CreateSjForContinuationWithEnv(){ SourceLocation Loc = Tok.getLocation(); StmtResult IfRes; ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, true/* C99 or CXX */); ExprResult CondExp; Decl *CondVar = 0; CondExp = LookupAndDeclareName(CreateIdentifierInfo("setjmp", Loc)); ExprVector ArgExprs; ExprResult __envExprRes = CondExp.get(); __envExprRes = LookupAndDeclareName(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc)); __envExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc), __envExprRes.take(), false); ArgExprs.push_back(__envExprRes.release()); CondExp = Actions.ActOnCallExpr(getCurScope(), CondExp.take(), Loc, ArgExprs, Loc, 0); CondExp = Actions.ActOnBooleanCondition(getCurScope(), Loc, CondExp.get()); FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), Loc)); ParseScope InnerScope(this, Scope::DeclScope,false); SourceLocation InnerStatementTrailingElseLoc; StmtResult StmtRes; ParseScope CompoundScope(this, Scope::DeclScope); PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in create setjmp statement for CbC"); StmtVector innerStmts; StmtResult innerStmtRes; ExprResult innerExprRes; innerExprRes = LookupAndDeclareName(CreateUniqueIdentifierInfo(__CBC_RETVAL_NAME, Loc)); innerStmtRes = Actions.ActOnReturnStmt(Loc, innerExprRes.take()); if (innerStmtRes.isUsable()) innerStmts.push_back(innerStmtRes.release()); StmtRes = Actions.ActOnCompoundStmt(Loc, Loc,innerStmts, false); StmtResult ThenStmt(StmtRes); InnerScope.Exit(); IfScope.Exit(); StmtResult ElseStmt; IfRes = Actions.ActOnIfStmt(Loc, FullCondExp, CondVar, ThenStmt.get(),Loc, ElseStmt.get()); return IfRes; } ExprResult Parser::LookupAndDeclareName(IdentifierInfo *II){ SourceLocation Loc = Tok.getLocation(); UnqualifiedId Name; CXXScopeSpec SS; SourceLocation TemplateKWLoc; ExternalSpace::CastExpressionIdValidator Validator(false,true); bool IsAddressOfOperand = false; Name.setIdentifier(II, Loc); return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, false, IsAddressOfOperand, &Validator); } ExprResult Parser::LookupMemberAndBuildExpr(IdentifierInfo *II, Expr* Base, bool IsArrow){ SourceLocation Loc = Tok.getLocation(); ExprResult Res; CXXScopeSpec SS; UnqualifiedId Name; SourceLocation TemplateKWLoc; Name.setIdentifier(II,Loc); TemplateArgumentListInfo TemplateArgsBuffer; DeclarationNameInfo NameInfo; const TemplateArgumentListInfo *TemplateArgs; Actions.DecomposeUnqualifiedId(Name, TemplateArgsBuffer, NameInfo, TemplateArgs); Res = Actions.MaybeConvertParenListExprToParenExpr(getCurScope(), Base); Base = Res.take(); LookupResult R(Actions, NameInfo, Actions.LookupMemberName); ExprResult BaseResult = Actions.Owned(Base); Actions.LookupMemberExpr(R, BaseResult, IsArrow, Loc, SS, 0, TemplateArgs != 0); Base = BaseResult.take(); Sema::ActOnMemberAccessExtraArgs ExtraArgs = {getCurScope(), Name, 0, false}; 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, 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; const char *PrevSpec = 0; unsigned DiagID = 0; FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, __CBC_STRUCT_POINTER_NAME)); FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_int, Loc, __CBC_STRUCT_ENV_NAME)); 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); } Decl* Parser::Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name){ ParsingDeclSpec PDS(*this); setTST(&PDS, T); 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, 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, SourceLocation Loc) { int length = strlen(Name); Token TokenForII; TokenForII.startToken(); TokenForII.setLocation(Loc); TokenForII.setLength(length); 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; } IdentifierInfo* Parser::CreateUniqueIdentifierInfo(const char* Name, SourceLocation Loc){ IdentifierInfo *II; std::ostringstream os; os << curFuncName << ".." /* separator */ << Name; II = CreateIdentifierInfo(os.str().c_str(), Loc); return II; } 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(); 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)); D.SetIdentifier(CreateUniqueIdentifierInfo(__CBC_RET_CODE_BASE_NAME, Loc),Loc); ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|Scope::FunctionDeclarationScope); bool IsAmbiguous = false; bool HasProto = true; 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; ParmVarDecl *Param; IdentifierInfo *retvalII = CreateIdentifierInfo(__CBC_RETVAL_NAME, Loc); 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); 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, VolatileQualifierLoc, SourceLocation(), ESpecType, ESpecRange.getBegin(), DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(), NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, Loc, Loc, D, TrailingReturnType), FnAttrs, Loc); PrototypeScope.Exit(); Decl *TheDecl; ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); Decl *BodyRes = Actions.ActOnStartOfFunctionDef(getCurScope(), D); D.complete(BodyRes); D.getMutableDeclSpec().abort(); Actions.ActOnDefaultCtorInitializers(BodyRes); StmtResult FnBody; StmtVector FnStmts; StmtResult innerR; ExprResult retvalAssginmentExpr,LHS; ExprVector ArgExprs; CommaLocsTy CommaLocs; DeclSpec envDS(AttrFactory); IdentifierInfo *structName = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc); setTST(&envDS, DeclSpec::TST_struct, structName); Declarator envDInfo(envDS, Declarator::TypeNameContext); envDInfo.SetRangeEnd(Loc); DeclSpec starDS(AttrFactory); starDS.Finish(Diags, PP); envDInfo.SetIdentifier(0,Loc); envDInfo.AddTypeInfo(DeclaratorChunk::getPointer(starDS.getTypeQualifiers(), Loc, starDS.getConstSpecLoc(), starDS.getVolatileSpecLoc(), starDS.getRestrictSpecLoc()), starDS.getAttributes(), SourceLocation()); ExprVector ArgExprs2; LHS = LookupAndDeclareName(envII); ArgExprs2.push_back(LHS.release()); LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs2); Expr *envCastExpr = LHS.take(); TypeSourceInfo *castTInfo = Actions.GetTypeForDeclaratorCast(envDInfo, envCastExpr->getType()); LHS = Actions.MaybeConvertParenListExprToParenExpr(getCurScope(), envCastExpr); envCastExpr = LHS.take(); LHS = Actions.BuildCStyleCastExpr(Loc, castTInfo, Loc, envCastExpr); ArgExprs.push_back(LHS.release()); LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs); LHS = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc), LHS.take(), true); Expr *ret_pCastExpr = LHS.take(); 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); retvalAssginmentExpr = Actions.ActOnBinOp(getCurScope(), Loc, tok::equal, LHS.take(), RHS.take()); innerR = Actions.ActOnExprStmt(retvalAssginmentExpr); if(innerR.isUsable()) FnStmts.push_back(innerR.release()); Token Next,ljTok; Next.setKind(tok::l_paren); ExternalSpace::StatementFilterCCC CCCValidator(Next); CXXScopeSpec SS; IdentifierInfo *ljName = CreateIdentifierInfo("longjmp", Loc); Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, ljName, Loc, Next, false, &CCCValidator); ljTok.startToken(); ljTok.setLocation(Loc); ljTok.setIdentifierInfo(ljName); ljTok.setKind(tok::annot_primary_expr); setExprAnnotation(ljTok, Classification.getExpression()); ljTok.setAnnotationEndLoc(Loc); PP.AnnotateCachedTokens(ljTok); ExprResult ljExpr,ljLHS; ljExpr = getExprAnnotation(ljTok); ExprVector ljArgExprs; DeclSpec ljDS(AttrFactory); setTST(&ljDS, DeclSpec::TST_struct, structName); Declarator ljD(ljDS, Declarator::TypeNameContext); ljD.SetRangeEnd(Loc); DeclSpec starDS2(AttrFactory); starDS2.Finish(Diags, PP); ljD.ExtendWithDeclSpec(starDS2); ljD.SetIdentifier(0, Loc); ljD.AddTypeInfo(DeclaratorChunk::getPointer(ljDS.getTypeQualifiers(), Loc, ljDS.getConstSpecLoc(), ljDS.getVolatileSpecLoc(), ljDS.getRestrictSpecLoc()), ljDS.getAttributes(), SourceLocation()); ljLHS = LookupAndDeclareName(envII); Expr *ljCastExpr = ljLHS.take(); TypeSourceInfo *ljCastTInfo = Actions.GetTypeForDeclaratorCast(ljD, ljCastExpr->getType()); ljLHS = Actions.BuildCStyleCastExpr(Loc, ljCastTInfo, Loc, ljCastExpr); ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.take()); ljLHS = LookupMemberAndBuildExpr(envII, ljLHS.take(), true); ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.take()); ljArgExprs.push_back(ljLHS.release()); CommaLocs.push_back(Loc); ljLHS = Actions.ActOnIntegerConstant(Loc, 1 /* return value for setjmp */); ljArgExprs.push_back(ljLHS.release()); ljExpr = Actions.ActOnCallExpr(getCurScope(), ljExpr.take(), Loc, ljArgExprs, Loc, 0); innerR = Actions.ActOnExprStmt(ljExpr); if(innerR.isUsable()) FnStmts.push_back(innerR.release()); FnBody = Actions.ActOnCompoundStmt(Loc, Loc, FnStmts, false); BodyScope.Exit(); TheDecl = Actions.ActOnFinishFunctionBody(BodyRes, FnBody.take()); returnDecl = Actions.ConvertDeclToDeclGroup(TheDecl); (&Actions.getASTConsumer())->HandleTopLevelDecl(returnDecl.get()); Actions.CurScope = SavedScope; Actions.CurContext = SavedContext; Actions.FunctionScopes.push_back(SavedFSI); return false; } ParmVarDecl* Parser::CreateParam(IdentifierInfo *II, int pointerNum, DeclSpec::TST T){ SourceLocation Loc = Tok.getLocation(); DeclSpec DS(AttrFactory); setTST(&DS, T); Declarator ParamDeclarator(DS, Declarator::PrototypeContext); ParamDeclarator.SetIdentifier(II, Loc); for(int i = 0;i<pointerNum; i++){ DeclSpec pointerDS(AttrFactory); pointerDS.Finish(Diags, PP); ParamDeclarator.AddTypeInfo(DeclaratorChunk::getPointer(pointerDS.getTypeQualifiers(), Loc, pointerDS.getConstSpecLoc(), pointerDS.getVolatileSpecLoc(), pointerDS.getRestrictSpecLoc()), pointerDS.getAttributes(),SourceLocation()); } ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Actions.ActOnParamDeclarator(getCurScope(), ParamDeclarator)); return Param; } void Parser::setTST(DeclSpec *DS, DeclSpec::TST T, IdentifierInfo* Name){ SourceLocation Loc = Tok.getLocation(); 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); DeclResult TagOrTempResult = true; bool Owned = false; bool IsDependent = false; MultiTemplateParamsArg TParams; TagOrTempResult = Actions.ActOnTag(getCurScope(), T, Sema::TUK_Reference, Loc, SS, Name, Loc, attrs.getList(), AS_none, DS->getModulePrivateSpecLoc(), TParams, Owned, IsDependent, SourceLocation(), false, 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); DS->Finish(Diags, PP); 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; } } void Parser::IncludeHeader(const char* HeaderName){ SourceLocation Loc = Tok.getLocation(); LookupResult R(Actions, CreateIdentifierInfo("setjmp", Loc), Loc, Actions.LookupOrdinaryName, Actions.ForRedeclaration); if (!Actions.LookupName(R, getCurScope())){ PP.LexHeader(Tok, HeaderName); ConsumeToken(); } } #endif