view clang/lib/Parse/ParseCbC.cpp @ 266:00f31e85ec16 default tip

Added tag current for changeset 31d058e83c98
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 14 Oct 2023 10:13:55 +0900
parents 011663b4a808
children
line wrap: on
line source

#ifndef noCbC

#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/Lookup.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Sema/ScopeInfo.h"

#include <sstream>
#include <string>
#include "CbCHelper.h"

using namespace clang;

/// The class which belong to this namespace is from other files' namespace.
/// Because those namespaces are unnamed namespaces, we can't access them.
/// So create this namespace and copy classes from those namespaces.
namespace ExternalSpace { // from ParseExpr.cpp , ParseStmt.cpp
    class CastExpressionIdValidator final : public CorrectionCandidateCallback {
     public:
      CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes)
          : NextToken(Next), AllowNonTypes(AllowNonTypes) {
        WantTypeSpecifiers = WantFunctionLikeCasts = AllowTypes;
      }

      bool ValidateCandidate(const TypoCorrection &candidate) override {
        NamedDecl *ND = candidate.getCorrectionDecl();
        if (!ND)
          return candidate.isKeyword();

        if (isa<TypeDecl>(ND))
          return WantTypeSpecifiers;

        if (!AllowNonTypes || !CorrectionCandidateCallback::ValidateCandidate(candidate))
          return false;

        if (!NextToken.isOneOf(tok::equal, tok::arrow, tok::period))
          return true;

        for (auto *C : candidate) {
          NamedDecl *ND = C->getUnderlyingDecl();
          if (isa<ValueDecl>(ND) && !isa<FunctionDecl>(ND))
            return true;
        }
        return false;
      }

      std::unique_ptr<CorrectionCandidateCallback> clone() override {
        return std::make_unique<CastExpressionIdValidator>(*this);
      }

     private:
      Token NextToken;
      bool AllowNonTypes;
    };

    class StatementFilterCCC final : public CorrectionCandidateCallback {
    public:
      StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
        WantTypeSpecifiers = nextTok.isOneOf(tok::l_paren, tok::less, tok::l_square,
                                             tok::identifier, tok::star, tok::amp);
        WantExpressionKeywords =
            nextTok.isOneOf(tok::l_paren, tok::identifier, tok::arrow, tok::period);
        WantRemainingKeywords =
            nextTok.isOneOf(tok::l_paren, tok::semi, tok::identifier, tok::l_brace);
        WantCXXNamedCasts = false;
      }

      bool ValidateCandidate(const TypoCorrection &candidate) override {
        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);
      }

      std::unique_ptr<CorrectionCandidateCallback> clone() override {
        return std::make_unique<StatementFilterCCC>(*this);
      }

    private:
      Token NextToken;
    };
}

/// Prepare__retForGotoWithTheEnvExpr - Prepare __CbC_return, code segment for returning and some necessary statements.
/// It is called when the parser find __return and statements are put into complex statement.
/// 
/// examples which are created:
///   complex statement:
///         ({
///           __code (*__CbC_return)(return_type, void*);
///           __CbC_return = code_segment_for_return;
///           __CbC_return;
///         });

ExprResult Parser::Prepare__retForGotoWithTheEnvExpr(){

  if (isVoidFunction()) { // error check : function type is void or not.
    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "continuation with the environment cannot use in the void function");
    Diag(Tok, DiagID);
    return ExprError();
  }
  // std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("({auto x = 1 + 1;})"));

  StmtResult innerRes;
  SourceLocation Loc = Tok.getLocation();
  IdentifierInfo *__CbC_retII = CreateIdentifierInfo("__CbC_cont", Loc);
  IdentifierInfo *retcsII = CreateUniqueIdentifierInfo(__CBC_RET_CODE_BASE_NAME, Loc);
  Create__CbC_envStruct(Loc, AS_none);

  Actions.ActOnStartStmtExpr();
  StmtResult CompoundStmtRes;
  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in compound statement ('{}')");
  StmtVector CompoundStmts; 

  ConsumeAnyToken(); // eat the '__return'.
  // create code segment for return to C's function
  CreateRetCS(retcsII);
    
  // __code (*__CbC_return)();
  innerRes = CreateDeclStmt(__CbC_retII, true, false, 0, DeclSpec::TST___code);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());

  // __CbC_return = ret;
  innerRes = CreateAssignmentStmt(__CbC_retII, retcsII);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());

  // __CbC_return;
  innerRes = CreateComplexStmtRet(__CbC_retII, false);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());
  Sema::CompoundScopeRAII CompoundScope(Actions);
  CompoundStmtRes = Actions.ActOnCompoundStmt(Loc,Loc,CompoundStmts,true);

  return Actions.ActOnStmtExpr(getCurScope(),Loc, CompoundStmtRes.get(), Loc);
}

#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/Token.h"

bool Parser::isBuiltinSetjmpDefined() {
    return Actions.getASTContext().getTargetInfo().hasSjLjLowering();
}

/// Prepare__envForGotoWithTheEnvExpr - Prepare __CbC_environment, struct __CbC_env and some necessary statements.
/// It is called when the parser find __environment and statements are put into complex statement.
/// 
/// examples which are created:
///   complex statement:
///         ({
///           volatile struct __CbC_env __CbC_environment;
///           jmp_buf env_buf;  --> int env_buf[64];
///           extern int setjmp(jmp_buf);
///           return_type retval;
///           __CbC_environment.ret_p = &retval;
///           __CbC_environment.env = &env_buf;
///           if (setjmp(__CbC_environment.env)){
///             return retval;
///           }
///           &__CbC_environment;
///         });
///   struct __CbC_env:
///         struct __CbC_env{
///           void *ret_p,*env;
///         }

//
// Compile from String
//   make sure to CosumeToken() before call this function.
//
void Parser::CompileFromString(const char *str, StmtVector &CompoundStmts){
  SourceLocation Loc = Tok.getLocation();
  Token TokSave = Tok;
  SourceLocation PLocSave = PrevTokLocation;
  PP.ReadFromString(str,Loc); 
  ConsumeAnyToken();
  while(! Tok.is(tok::eof)) {
      StmtVector Stmts;
      StmtResult innerRes;
      innerRes = ParseStatementOrDeclaration(Stmts,( ParsedStmtContext::Compound | ParsedStmtContext::AllowDeclarationsInC));
      if (innerRes.isUsable())
        CompoundStmts.push_back(innerRes.get());
  }
  Tok = TokSave ;
  PrevTokLocation= PLocSave ;
}

ExprResult Parser::Prepare__envForGotoWithTheEnvExpr(){

  if (isVoidFunction()) { // error check : function type is void or not.
    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "continuation with the environment cannot use in the void function");
    Diag(Tok, DiagID);
    return ExprError();
  }

  Sema::CompoundScopeRAII CompoundScope(Actions);
  StmtResult innerRes;
  SourceLocation Loc = Tok.getLocation();
  IdentifierInfo *bufII = CreateIdentifierInfo(__CBC_BUF_NAME, Loc);
  IdentifierInfo *retvalII = CreateIdentifierInfo(__CBC_RETVAL_NAME, Loc);
  IdentifierInfo *structII = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc);
  IdentifierInfo *__CbC_envII = CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc);
  IdentifierInfo *envII = CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc);
  IdentifierInfo *ret_pII = CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc);
  Create__CbC_envStruct(Loc, AS_none);
  Actions.ActOnStartStmtExpr();

  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in compound statement ('{}')");
  StmtVector CompoundStmts; 
  ExprResult Result(true);
  
 // struct __CbC_env __CbC_environment;
  innerRes = CreateDeclStmt(__CbC_envII, false, false, 0, DeclSpec::TST_struct, structII, DeclSpec::TQ_volatile);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());

  // returnType retval;
  innerRes = CreateDeclStmt(retvalII, false, true);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());

  ConsumeAnyToken(); // eat the '__environment'.
  if (isBuiltinSetjmpDefined()) {
      CompileFromString("int env_buf[64];",CompoundStmts); // 4*64 is enough for every arch right now
  } else {
      CompileFromString("int env_buf[64];extern int setjmp(void *);",CompoundStmts); 
  }

  // __CbC_environment.ret_p = &retval;
  innerRes = CreateAssignmentStmt(__CbC_envII, retvalII, true, true, ret_pII);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());

  // __CbC_environment.env = env_buf;
  innerRes = CreateAssignmentStmt(__CbC_envII, bufII, true, false, envII);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());

  // create statements of setjmp
  innerRes = CreateSjForContinuationWithTheEnv();
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());
  
  // __CbC_environment;
  innerRes = CreateComplexStmtRet(__CbC_envII, true);
  if (innerRes.isUsable())
    CompoundStmts.push_back(innerRes.get());

  StmtResult CompoundStmtRes = Actions.ActOnCompoundStmt(Loc,Loc,CompoundStmts,true);
  Result =  Actions.ActOnStmtExpr(getCurScope() ,Loc, CompoundStmtRes.get(), Loc);

  // cast 
  ParsedType CastTy;
  DeclSpec void_DS(AttrFactory);
  setTST(&void_DS, DeclSpec::TST_void);
  Declarator DeclaratorInfo(void_DS, ParsedAttributesView::none(), DeclaratorContext::TypeName);
  DeclSpec star_DS(AttrFactory);
  star_DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());
  DeclaratorInfo.ExtendWithDeclSpec(star_DS);
  DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
  DeclaratorInfo.AddTypeInfo(DeclaratorChunk::getPointer(star_DS.getTypeQualifiers(), Loc,star_DS.getConstSpecLoc(),star_DS.getVolatileSpecLoc(),
                                                         star_DS.getRestrictSpecLoc(),star_DS.getAtomicSpecLoc(),star_DS.getUnalignedSpecLoc()),std::move(star_DS.getAttributes()),SourceLocation());
  return Actions.ActOnCastExpr(getCurScope(), Loc, DeclaratorInfo, CastTy,Loc, Result.get());
  
}

/// CreateAssignmentStmt - Create assignment statement such as "aaa = bbb;", "auaua = llll;", etc.
/// It can create 4 kinds of statement.
/// 1. common assignment statement:
///         variable '=' variable ';'
/// 2. LHS variable is member of struct:
///         structVar '.' member '=' variable ';'
/// 3. RHS variable is address of operand:
///         variable '=' '&' variable ';'
/// 4. 2+3:
///         structVar '.' member '=' '&' variable ';'
StmtResult Parser::CreateAssignmentStmt(IdentifierInfo* LHSII, IdentifierInfo* RHSII, bool LHSisMemberAccess, bool RHShasAmp,
                                        IdentifierInfo* extraLHSII, IdentifierInfo* extraRHSII){
  ExprResult Expr,LHS,RHS;
  
  Token Next,LHSToken;
  SourceLocation Loc = Tok.getLocation();
  CXXScopeSpec SS;
  Next.startToken();
  if (LHSisMemberAccess) 
     Next.setKind(tok::period);
  else
     Next.setKind(tok::equal);
  LHSToken.startToken();
  LHSToken.setLocation(Loc);
  LHSToken.setIdentifierInfo(LHSII);
  LHSToken.setKind(tok::identifier);
  ExternalSpace::StatementFilterCCC SFCCC(Next);
  Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, LHSII, Loc, Next, SS.isEmpty() ? &SFCCC : nullptr);
  if (Classification.getKind() == Sema::NC_NonType) {
     Token Tok;
     Tok.startToken();
     Tok.setKind(tok::annot_non_type);
     setNonTypeAnnotation(Tok, Classification.getNonTypeDecl());
     Tok.setLocation(Loc);
     Tok.setAnnotationEndLoc(Loc);
     NamedDecl *ND = getNonTypeAnnotation(Tok);
     LHS = Actions.ActOnNameClassifiedAsNonType(getCurScope(), SS, ND, Loc, Tok);
  } else { 
     setExprAnnotation(LHSToken, Classification.getExpression());
     LHSToken.setAnnotationEndLoc(Loc);
     PP.AnnotateCachedTokens(LHSToken);
     LHS = getExprAnnotation(LHSToken);
  }
  if (LHSisMemberAccess) 
    LHS = LookupMemberAndBuildExpr(extraLHSII, LHS.get(), false);
  
  RHS = LookupNameAndBuildExpr(RHSII);
  if (RHShasAmp)
    RHS = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::amp, RHS.get());

  Expr = Actions.ActOnBinOp(getCurScope(), Loc,tok::equal,LHS.get(),RHS.get());
  
  return Actions.ActOnExprStmt(Expr);
}

/// CreateDeclStmt - Create declaration statement such as "int aaa;".
/// If isRetCS is true, create code segment for return to C's function. And Name is name of code segment.
/// If copyType is true, type of variable is copied from callee.
StmtResult Parser::CreateDeclStmt(IdentifierInfo *II, bool isRetCS, bool copyType, int array, DeclSpec::TST valueType, IdentifierInfo* Name, DeclSpec::TQ TQ){
  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
  SourceLocation Loc = Tok.getLocation();
  DeclGroupPtrTy DeclGPT;
  ParsingDeclSpec DS(*this);
  DeclSpec *DSp;
  DSp = &DS;

  setTST(&DS, valueType, Name, TQ);
  ParsedAttributes LocalAttrs(AttrFactory);
  // LocalAttrs.takeAllFrom(Attrs);
  ParsingDeclarator D(*this, DS, LocalAttrs, static_cast<DeclaratorContext>(DeclaratorContext::Block));
  D.SetIdentifier(II, Loc);
    
  if (array) {
    DeclSpec FDS(AttrFactory);
    D.AddTypeInfo(DeclaratorChunk::getArray(0,false,false,Actions.ActOnIntegerConstant(Loc,array).get(),Loc, FDS.getConstSpecLoc() ),
            std::move(FDS.getAttributes()), SourceLocation());
  }
  if (isRetCS) {
    D.setEllipsisLoc(SourceLocation());
    bool hadGroupingParens = D.hasGroupingParens();
    D.setGroupingParens(true);
    D.SetRangeEnd(Loc);
    DeclSpec FDS(AttrFactory);
    DS.Finish(Actions, Policy);
    
    D.AddTypeInfo(DeclaratorChunk::getPointer(FDS.getTypeQualifiers(), Loc, FDS.getConstSpecLoc(), FDS.getVolatileSpecLoc(),
                                              FDS.getRestrictSpecLoc(), DS.getAtomicSpecLoc(), FDS.getUnalignedSpecLoc()), std::move(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; 
    DeclSpec FPDS(AttrFactory);
    bool RefQualifierIsLValueRef = true;
    ExceptionSpecificationType ESpecType = EST_None;
    SourceRange ESpecRange;
    SmallVector<ParsedType, 2> DynamicExceptions;
    SmallVector<SourceRange, 2> DynamicExceptionRanges;
    ExprResult NoexceptExpr;
    CachedTokens *ExceptionSpecTokens = 0;
    ParsedAttributes FnAttrs(AttrFactory);
    TypeResult TrailingReturnType;

    ParmVarDecl *Param;
    FunctionDecl *CurFunctionDecl = Actions.getCurFunctionDecl();
    QualType CurFuncResQT = CurFunctionDecl->getReturnType();
    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;
    SmallVector<NamedDecl *, 0> DeclsInPrototype;
    D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, ESpecType, Loc, ParamInfo.data(),
                                               ParamInfo.size(), EllipsisLoc, Loc, 
                                               RefQualifierIsLValueRef, RefQualifierLoc,
                                               /*MutableLoc=*/SourceLocation(),
                                               ESpecType, ESpecRange.getBegin(),
                                               DynamicExceptions.data(), DynamicExceptionRanges.data(),
                                               DynamicExceptions.size(),
                                               // DynamicExceptions,
                                               NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr, 
                                               ExceptionSpecTokens, DeclsInPrototype, Loc, Loc, 
                                               D, TrailingReturnType,Loc, &FPDS),
                  std::move(FnAttrs), Loc);
    PrototypeScope.Exit();
    DSp = &FDS;
  }
  
  SmallVector<Decl *, 8> DeclsInGroup;
  Decl *FirstDecl;
  
  if (copyType)
    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);
}


/// handleDeclAndChangeDeclType - 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(FunctionDefinitionKind::Declaration);
  DeclarationNameInfo NameInfo = Actions.GetNameForDeclarator(D);
  DeclContext *DC = Actions.CurContext;
  QualType R = Actions.getCurFunctionDecl()->getReturnType(); // copy a type
  TypeSourceInfo *TInfo = Actions.Context.CreateTypeSourceInfo(R); // copy a type infomation
  Scope *S = getCurScope();
  LookupResult Previous(Actions, NameInfo, Actions.LookupOrdinaryName, Actions.ForVisibleRedeclaration);
  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;
}

/// CreateSjForContinuationWithEnv - Create statements of setjmp for continuation with the environment.
///   code example:
///         if (setjmp(__CbC_environment.env)){
///           return retval;
///         }
StmtResult Parser::CreateSjForContinuationWithTheEnv(){
  SourceLocation Loc = Tok.getLocation();
  StmtResult IfRes;
  ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, true/* C99 or CXX */);
  ExprResult CondExp;
  StmtResult InitStmt;
  Sema::ConditionResult Cond;

  if (isBuiltinSetjmpDefined()) {
      CondExp = LookupNameAndBuildExpr(CreateIdentifierInfo("__builtin_setjmp", Loc));
  } else {
      CondExp = LookupNameAndBuildExpr(CreateIdentifierInfo("setjmp", Loc));
  }
  ExprVector ArgExprs;
  ExprResult __envExprRes = CondExp.get();

  __envExprRes = LookupNameAndBuildExpr(CreateIdentifierInfo(__CBC_ENVIRONMENT_NAME, Loc));
  __envExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_ENV_NAME, Loc), __envExprRes.get(), false);

  ArgExprs.push_back(__envExprRes.get());
  CondExp = Actions.ActOnCallExpr(getCurScope(), CondExp.get(), Loc, ArgExprs, Loc, 0);
  Cond    = Actions.ActOnCondition(getCurScope(), Loc, CondExp.get(), Sema::ConditionKind::Boolean);


  ParseScope InnerScope(this, Scope::DeclScope,false);
    
  StmtResult StmtRes;
  Sema::CompoundScopeRAII CompoundScope(Actions);
  PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),Loc,"in create setjmp statement for CbC");
  StmtVector innerStmts;
  StmtResult innerStmtRes;
  ExprResult innerExprRes;
  innerExprRes = LookupNameAndBuildExpr(CreateIdentifierInfo(__CBC_RETVAL_NAME, Loc));
  innerStmtRes = Actions.ActOnReturnStmt(Loc, innerExprRes.get(), getCurScope());
  if (innerStmtRes.isUsable())
    innerStmts.push_back(innerStmtRes.get());
  StmtRes = Actions.ActOnCompoundStmt(Loc, Loc,innerStmts, false);
  StmtResult ThenStmt(StmtRes);
  InnerScope.Exit();
  IfScope.Exit();
  StmtResult ElseStmt;
  IfRes = Actions.ActOnIfStmt(Loc, IfStatementKind::Ordinary, Loc, InitStmt.get(), Cond, Loc, ThenStmt.get(),Loc, ElseStmt.get());
  return IfRes;
}


/// LookupNameAndBuildExpr - Look up name, create ExprResult and return it.
ExprResult Parser::LookupNameAndBuildExpr(IdentifierInfo *II, bool IsAddressOfOperand){
  SourceLocation Loc = Tok.getLocation();
  UnqualifiedId Name;
  CXXScopeSpec SS;
  SourceLocation TemplateKWLoc;
  ExternalSpace::CastExpressionIdValidator Validator(Tok,false,true);
  Name.setIdentifier(II, Loc);
  return Actions.ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Name, false, IsAddressOfOperand, &Validator);
}

/// LookupMemberAndBuildExpr - Look up member name, create ExprResult and return it.
/// If IsArrow is true, the name is accessed by arrow operand.
ExprResult Parser::LookupMemberAndBuildExpr(IdentifierInfo *II, Expr* Base, bool IsArrow){
  SourceLocation Loc = Tok.getLocation();
  CXXScopeSpec SS;
  UnqualifiedId Name;
  SourceLocation TemplateKWLoc;
  tok::TokenKind OpKind = (IsArrow ? tok::arrow : tok::period);
  Name.setIdentifier(II,Loc);
  return Actions.ActOnMemberAccessExpr(getCurScope(), Base, Loc, OpKind, SS, TemplateKWLoc, Name, nullptr);
}


/// 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.
///   The example of struct which is created :
///        struct __CbC_env{
///          void *ret_p,*env;
///        };
void Parser::Create__CbC_envStruct(SourceLocation Loc, AccessSpecifier AS) {

  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.ForVisibleRedeclaration);
  if(Actions.LookupName(Previous, getCurScope()))
    return;

  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;

  ParsingDeclSpec SDS(*this);
  SDS.SetRangeStart(Loc);
  SDS.SetRangeEnd(Loc);
  DeclSpec::TST TagType = DeclSpec::TST_struct;
  DeclResult TagOrTempResult = true;
  bool Owned = false;
  bool IsDependent = false;
  ParsedAttributes attrs(AttrFactory);
  MultiTemplateParamsArg TParams;
  Sema::SkipBodyInfo SkipBody; 
  TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, Sema::TUK_Definition, Loc,
                                     SDS.getTypeSpecScope(), Name, Loc, attrs, AS,
                                     SDS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
                                     SourceLocation(), false, clang::TypeResult(), false, false,OffsetOfState,&SkipBody);

  Decl *TagDecl = TagOrTempResult.get();
  PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, Loc, "parsing struct/union body");
  ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
  Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
  SmallVector<Decl *, 32> FieldDecls;

  FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, __CBC_STRUCT_POINTER_NAME));
  FieldDecls.push_back(Create__CbC_envBody(TagDecl, DeclSpec::TST_void, Loc, __CBC_STRUCT_ENV_NAME));

  Actions.ActOnFields(getCurScope(),Loc, TagDecl, FieldDecls,Loc, Loc,attrs);
  StructScope.Exit();
  Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, Loc);

  Actions.CurScope = SavedScope;
  Actions.CurContext = SavedContext;
  Actions.FunctionScopes.push_back(SavedFSI);
}

/// Create__CbC_envBody - Create void type pointer ret_p and env which are member of __CbC_env.
Decl* Parser::Create__CbC_envBody(Decl* TagDecl, DeclSpec::TST T, SourceLocation Loc, const char* Name){
  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
  ParsingDeclSpec PDS(*this);
  setTST(&PDS, T);
  SourceLocation CommaLoc;
  ParsedAttributes LocalAttrs(AttrFactory);
  // LocalAttrs.takeAllFrom(Attrs);
  ParsingFieldDeclarator DeclaratorInfo(*this, PDS, LocalAttrs);
  DeclaratorInfo.D.setCommaLoc(CommaLoc);
  DeclaratorInfo.D.SetRangeEnd(Loc);
  DeclSpec DS(AttrFactory);
  DS.Finish(Actions, Policy);
  DeclaratorInfo.D.SetIdentifier(CreateIdentifierInfo(Name, Loc),Loc);

  DeclaratorInfo.D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(),
                                                           DS.getVolatileSpecLoc(),DS.getRestrictSpecLoc(), DS.getAtomicSpecLoc(), DS.getUnalignedSpecLoc()),
                               std::move(DS.getAttributes()),SourceLocation());
  Decl *Field = Actions.ActOnField(getCurScope(), TagDecl,
                                   DeclaratorInfo.D.getDeclSpec().getSourceRange().getBegin(),
                                   DeclaratorInfo.D, DeclaratorInfo.BitfieldSize);
  DeclaratorInfo.complete(Field);
  return Field;
}

/// CreateIdentifierInfo - Create IdentifierInfo from char pointer.
///   usage : 
///          IdentifierInfo *II = CreateIdentifierInfo(IIName, Kind, Location);

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(TokenForII.getRawIdentifier());
  TokenForII.setIdentifierInfo(II);
  TokenForII.setKind(II->getTokenID());
  return II;
}

/// CreateUniqueIdentifierInfo - Create unique IdentifierInfo.
/// IdentifierInfos have unique name which were created by this function.
/// Naming conventions : 
///   current 'function name' '..' 'variable name' 'uniqueID'
/// For example, if current function's name is 'main' and variable name is 'auaua', IdentifierInfo's name is 'main..auaua'.
IdentifierInfo* Parser::CreateUniqueIdentifierInfo(const char* Name, SourceLocation Loc){
  IdentifierInfo *II;
  std::ostringstream os;
  
  os << curFuncName << ".." /* separator */ << Name << UniqueId;
  II = CreateIdentifierInfo(os.str().c_str(), Loc);
  UniqueId++; // Modify the unique ID.
  return II;
}

/// CreateRetCS - Create code segment which is used for continuation with the environment.
///   create these codes:
///         __code ret(return_type retval, void *env){
///           *(return_type)((struct CbC_environment *)(env))->ret_p = retval;
///             longjmp((void*)(((struct __CbC_environment *)env)->env),1);
///         }
void Parser::CreateRetCS(IdentifierInfo *csName){
  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
  QualType CurFuncResQT = Actions.getCurFunctionDecl()->getReturnType();
  
  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();
  ParsingDeclSpec PDS(*this);
  setTST(&PDS, DeclSpec::TST___code);
  ParsedAttributes LocalAttrs(AttrFactory);
  // LocalAttrs.takeAllFrom(Attrs);
  ParsingDeclarator D(*this, PDS, LocalAttrs, static_cast<DeclaratorContext>(DeclaratorContext::File));
  D.SetIdentifier(csName, Loc);
  ParseScope PrototypeScope(this,Scope::FunctionPrototypeScope|Scope::DeclScope|Scope::FunctionDeclarationScope);
  bool IsAmbiguous = false;
  bool HasProto = true;
  SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
  SourceLocation EllipsisLoc, RefQualifierLoc; 
  DeclSpec FDS(AttrFactory);
  bool RefQualifierIsLValueRef = true;
  ExceptionSpecificationType ESpecType = EST_None;
  SourceRange ESpecRange;
  SmallVector<ParsedType, 2> DynamicExceptions;
  SmallVector<SourceRange, 2> DynamicExceptionRanges;
  ExprResult NoexceptExpr;
  CachedTokens *ExceptionSpecTokens = 0;
  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));
  SmallVector<NamedDecl *, 0> DeclsInPrototype;

  D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto, IsAmbiguous, Loc, ParamInfo.data(), ParamInfo.size(), EllipsisLoc, Loc,
                                             RefQualifierIsLValueRef, RefQualifierLoc, 
                                             SourceLocation(),
                                             ESpecType, ESpecRange.getBegin(),
                                             DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(),
                                             NoexceptExpr.isUsable() ? NoexceptExpr.get() : 0, ExceptionSpecTokens, 
                                             DeclsInPrototype,
                                             Loc, Loc, D, TrailingReturnType, Loc, &FDS), std::move(FnAttrs), Loc);
  PrototypeScope.Exit();
  
  Decl *TheDecl;
  ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
  Sema::SkipBodyInfo SkipBody;
  const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo();
  Decl *BodyRes = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
                                                  TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams : MultiTemplateParamsArg(),
                                                  &SkipBody);

  D.complete(BodyRes);
  D.getMutableDeclSpec().abort();
  Actions.ActOnDefaultCtorInitializers(BodyRes);
  StmtResult FnBody;
  StmtVector FnStmts;
  StmtResult innerR;
  ExprResult retvalAssginmentExpr,LHS;
  ExprVector ArgExprs;
  // SourceLocation CommaLocs;
  DeclSpec envDS(AttrFactory);

  if (! isBuiltinSetjmpDefined()) {
      CompileFromString("extern void longjmp(void *,int);",FnStmts); 
  }

  IdentifierInfo *structName = CreateIdentifierInfo(__CBC_STRUCT_NAME, Loc);
  setTST(&envDS, DeclSpec::TST_struct, structName);

  Declarator envDInfo(envDS, ParsedAttributesView::none(), DeclaratorContext::TypeName);
  envDInfo.SetRangeEnd(Loc);
  DeclSpec starDS(AttrFactory);
  starDS.Finish(Actions, Policy);
  envDInfo.SetIdentifier(0,Loc);
  envDInfo.AddTypeInfo(DeclaratorChunk::getPointer(starDS.getTypeQualifiers(), Loc,
                                                   starDS.getConstSpecLoc(),
                                                   starDS.getVolatileSpecLoc(),
                                                   starDS.getRestrictSpecLoc(),
                                                   starDS.getAtomicSpecLoc(),
                                                   starDS.getUnalignedSpecLoc()),
                       std::move(starDS.getAttributes()),
                       SourceLocation());
  {  // scope for RAII
  Sema::CompoundScopeRAII CompoundScope(Actions);
  ExprVector ArgExprs2;
  LHS = LookupNameAndBuildExpr(envII);
  ArgExprs2.push_back(LHS.get());
  LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs2);
  Expr *envCastExpr = LHS.get();
  TypeSourceInfo *castTInfo = Actions.GetTypeForDeclaratorCast(envDInfo, envCastExpr->getType());
  LHS = Actions.MaybeConvertParenListExprToParenExpr(getCurScope(), envCastExpr);
  envCastExpr = LHS.get();
  LHS = Actions.BuildCStyleCastExpr(Loc, castTInfo, Loc, envCastExpr);
  ArgExprs.push_back(LHS.get());	
  LHS = Actions.ActOnParenListExpr(Loc, Loc, ArgExprs);
  LHS = LookupMemberAndBuildExpr(CreateIdentifierInfo(__CBC_STRUCT_POINTER_NAME, Loc),
                                 LHS.get(), true);
  Expr *ret_pCastExpr = LHS.get();
  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 = LookupNameAndBuildExpr(retvalII);

  retvalAssginmentExpr = Actions.ActOnBinOp(getCurScope(), Loc, tok::equal, LHS.get(), RHS.get());
  innerR = Actions.ActOnExprStmt(retvalAssginmentExpr);
  if(innerR.isUsable())
    FnStmts.push_back(innerR.get());

  ExprResult ljExpr,ljLHS;
  if (isBuiltinSetjmpDefined()) {
      ljExpr = IIToExpr(CreateIdentifierInfo("__builtin_longjmp",  Loc), tok::l_paren);
  } else {
      ljExpr = IIToExpr(CreateIdentifierInfo("longjmp",  Loc), tok::l_paren);
  }
  ExprVector ljArgExprs;
  DeclSpec ljDS(AttrFactory);
  setTST(&ljDS, DeclSpec::TST_struct, structName);

  Declarator ljD(ljDS, ParsedAttributesView::none(), DeclaratorContext::TypeName);
  ljD.SetRangeEnd(Loc);
  DeclSpec starDS2(AttrFactory);
  starDS2.Finish(Actions, Policy);
  ljD.ExtendWithDeclSpec(starDS2);
  ljD.SetIdentifier(0, Loc);
  ljD.AddTypeInfo(DeclaratorChunk::getPointer(ljDS.getTypeQualifiers(), Loc,
                                              ljDS.getConstSpecLoc(),
                                              ljDS.getVolatileSpecLoc(),
                                              ljDS.getRestrictSpecLoc(),
                                              ljDS.getAtomicSpecLoc(),
                                              ljDS.getUnalignedSpecLoc()),
                  std::move(ljDS.getAttributes()),
                  SourceLocation());
  ljLHS = LookupNameAndBuildExpr(envII);
  Expr *ljCastExpr = ljLHS.get();
  TypeSourceInfo *ljCastTInfo = Actions.GetTypeForDeclaratorCast(ljD, ljCastExpr->getType());
  ljLHS = Actions.BuildCStyleCastExpr(Loc, ljCastTInfo, Loc, ljCastExpr);
  ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.get());
  ljLHS = LookupMemberAndBuildExpr(envII, ljLHS.get(), true);
  ljLHS = Actions.ActOnParenExpr(Loc, Loc, ljLHS.get());
  ljArgExprs.push_back(ljLHS.get());
  // CommaLocs.push_back(Loc);
  ljLHS = Actions.ActOnIntegerConstant(Loc, 1 /* return value for setjmp */);
  ljArgExprs.push_back(ljLHS.get());
  ljExpr = Actions.ActOnCallExpr(getCurScope(), ljExpr.get(), Loc, ljArgExprs, Loc, 0);
  innerR = Actions.ActOnExprStmt(ljExpr);
  if(innerR.isUsable())
    FnStmts.push_back(innerR.get());
  FnBody = Actions.ActOnCompoundStmt(Loc, Loc, FnStmts, false);
  } // RAII clear
  BodyScope.Exit();
  TheDecl = Actions.ActOnFinishFunctionBody(BodyRes, FnBody.get());
  returnDecl =  Actions.ConvertDeclToDeclGroup(TheDecl);
  (&Actions.getASTConsumer())->HandleTopLevelDecl(returnDecl.get());
  Actions.CurScope = SavedScope;
  Actions.CurContext = SavedContext;
  Actions.FunctionScopes.push_back(SavedFSI);
}

/// IIToExpr - Create ExprResult from IdentifierInfo. 
/// It is used when II is a not primary expression such as not primary types, a function's name, etc.
ExprResult Parser::IIToExpr(IdentifierInfo *II, tok::TokenKind Kind){
  SourceLocation Loc = Tok.getLocation();
  Token Next,IITok;
  Next.setKind(Kind);
  ExternalSpace::StatementFilterCCC CCCValidator(Next);
  CXXScopeSpec SS;
  Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, II, Loc, Next, &CCCValidator);
  IITok.startToken();
  IITok.setLocation(Loc);
  IITok.setIdentifierInfo(II);
  IITok.setKind(tok::annot_primary_expr);
  if (Classification.getKind() == Sema::NC_NonType) {
      IITok.setKind(tok::annot_non_type);
      setNonTypeAnnotation(IITok, Classification.getNonTypeDecl());
      IITok.setLocation(Loc);
      IITok.setAnnotationEndLoc(Loc);
      PP.AnnotateCachedTokens(IITok);
      const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
      if (SS.isNotEmpty())
          AnnotateScopeToken(SS, !WasScopeAnnotation);
      NamedDecl *ND = getNonTypeAnnotation(IITok);
      ExprResult E;
      return Actions.ActOnNameClassifiedAsNonType(getCurScope(), SS, ND, Loc, IITok);
  }
  setExprAnnotation(IITok, Classification.getExpression());
  IITok.setAnnotationEndLoc(Loc);
  PP.AnnotateCachedTokens(IITok);
  return getExprAnnotation(IITok);
}

/// CreateComplexStmtRet - Create return value for complex statements.
///
///   ({ /* some statements */
///      return_value; )};
///     ^^^^^^^^^^^^^ Create it.
StmtResult Parser::CreateComplexStmtRet(IdentifierInfo *II, bool IsAddressOfOperand){
  ExprResult ER;
  if (IsAddressOfOperand) {
    ER = LookupNameAndBuildExpr(II, true);
    ER = Actions.ActOnUnaryOp(getCurScope(), Tok.getLocation(), tok::amp, ER.get());
  }
  else
    ER = IIToExpr(II,tok::semi);
  return Actions.ActOnExprStmt(ER,false);
}

/// CreateParam - Create paramator for functions.
/// 
/// int funcname(int aua) { 
///              ^^^^^^^ Create it.
ParmVarDecl* Parser::CreateParam(IdentifierInfo *II, int pointerNum, DeclSpec::TST T){
  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
  SourceLocation Loc = Tok.getLocation();
  DeclSpec DS(AttrFactory);
  setTST(&DS, T);
  Declarator ParamDeclarator(DS, ParsedAttributesView::none(), DeclaratorContext::Prototype);
  ParamDeclarator.SetIdentifier(II, Loc);
  for(int i = 0;i<pointerNum; i++){
    DeclSpec pointerDS(AttrFactory);
    pointerDS.Finish(Actions, Policy);
    ParamDeclarator.AddTypeInfo(DeclaratorChunk::getPointer(pointerDS.getTypeQualifiers(), Loc,
                                                            pointerDS.getConstSpecLoc(),
                                                            pointerDS.getVolatileSpecLoc(),
                                                            pointerDS.getRestrictSpecLoc(),
                                                            pointerDS.getAtomicSpecLoc(),
                                                            pointerDS.getUnalignedSpecLoc()),
                                std::move(pointerDS.getAttributes()),SourceLocation());
  }
  ParmVarDecl *Param = dyn_cast<ParmVarDecl>(Actions.ActOnParamDeclarator(getCurScope(), ParamDeclarator));
  return Param;

}

/// setTST - set TypeSpecifierType(TST) DeclSpec.
/// TST is specifiers the kind of type such as int, double, char, etc.
void Parser::setTST(DeclSpec *DS, DeclSpec::TST T, IdentifierInfo* Name, DeclSpec::TQ TQ){
  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
  SourceLocation Loc = Tok.getLocation();
  bool isInvalid = false;
  const char *PrevSpec = 0;
  unsigned DiagID = 0;
  CXXScopeSpec SS;
  DS->SetRangeStart(Loc);
  DS->SetRangeEnd(Loc);
  if (TQ != DeclSpec::TQ_unspecified) {
    isInvalid = DS->SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
                               getLangOpts());
  }

  if (T == DeclSpec::TST_struct) {
    ParsedAttributes attrs(AttrFactory);
    DeclResult TagOrTempResult = true;
    bool Owned = false;
    bool IsDependent = false;
    MultiTemplateParamsArg TParams;
    Sema::SkipBodyInfo SkipBody; 
    TagOrTempResult = Actions.ActOnTag(getCurScope(), T, Sema::TUK_Reference, Loc,
                                       SS, Name, Loc, attrs, AS_none,
                                       DS->getModulePrivateSpecLoc(),
                                       TParams, Owned, IsDependent,
                                       SourceLocation(), false,
                                       clang::TypeResult(), false, false,OffsetOfState,&SkipBody);
    isInvalid = DS->SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, TagOrTempResult.get(), Owned, Policy);
  }
  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, &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()) {
      TypeResult TR = getTypeAnnotation(TypeTok);
      isInvalid = DS->SetTypeSpecType(T, Loc, PrevSpec, DiagID, TR, Policy);
    } else
      DS->SetTypeSpecError();
  }
  else
    isInvalid = DS->SetTypeSpecType(T, Loc, PrevSpec, DiagID, Policy);
  
  DS->Finish(Actions, Policy);
  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;
  }
}

/// CheckTheSjHeader - Check whether setjmp.h has been already included or not.
/// If not, include it.
void Parser::CheckTheSjHeader(){
#if 0
  SourceLocation Loc = Tok.getLocation();
  LookupResult R(Actions, CreateIdentifierInfo("setjmp", Loc), Loc, Actions.LookupOrdinaryName, Actions.ForVisibleRedeclaration);
  if (!Actions.LookupName(R, getCurScope())){ // look up the setjmp
    if (PP.IncludeHeader(Tok, "setjmp.h"))
      ConsumeToken();
  }
#endif
}

/// isVoidFunction - Return true if current function return type is void.
bool Parser::isVoidFunction(){
  return Actions.getCurFunctionDecl()->getReturnType().getTypePtr()->isVoidType();
}

/// ParseCbCGotoStatement
///       jump-statement:
/// [CbC]   'goto' codeSegment ';'
///
StmtResult Parser::ParseCbCGotoStatement(ParsedAttributes &Attrs,StmtVector &Stmts) {
  assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
  StmtVector CompoundedStmts;

  SourceLocation gotoLoc = ConsumeToken();  // eat the 'goto'.
  StmtResult gotoRes;
  Token TokAfterGoto = Tok;
  Stmtsp = &Stmts;

  ParsedStmtContext SubStmtCtx =
     ParsedStmtContext::Compound  |  ParsedStmtContext::InStmtExpr; // unconfident
  gotoRes = ParseStatementOrDeclaration(Stmts, SubStmtCtx);

  if (gotoRes.get() == NULL)
    return StmtError();
  else if (gotoRes.get()->getStmtClass() != Stmt::CallExprClass) { // if it is not function call
    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "expected identifier or codesegment call");
    Diag(TokAfterGoto, DiagID);
    return StmtError();
  }
  
  assert((Attrs.empty() || gotoRes.isInvalid() || gotoRes.isUsable()) &&
         "attributes on empty statement");
  if (!(Attrs.empty() || gotoRes.isInvalid()))
    gotoRes = Actions.ActOnAttributedStmt(Attrs,gotoRes.get());
  if (gotoRes.isUsable())
    CompoundedStmts.push_back(gotoRes.get());

  // add return; after goto codesegment();
  if (Actions.getCurFunctionDecl()->getReturnType().getTypePtr()->is__CodeType()) {
    ExprResult retExpr;
    StmtResult retRes;
    retRes = Actions.ActOnReturnStmt(gotoLoc, retExpr.get(), getCurScope());
    if (retRes.isUsable())
      CompoundedStmts.push_back(retRes.get());
  }
  Sema::CompoundScopeRAII CompoundScope(Actions);
  StmtResult R =  Actions.ActOnCompoundStmt(gotoLoc, Tok.getLocation(), CompoundedStmts, false);
  return R;
}

/// SearchCodeSegmentDeclaration - Read tokens until we get to the specified code segment declaration.
/// If we can't find it , return false;
bool Parser::SearchCodeSegmentDeclaration(std::string Name){
  while(SkipAnyUntil(tok::kw___code, StopBeforeMatch)){
    if(NextToken().is(tok::identifier) && NextToken().getIdentifierInfo()->getName().str() == Name)
      return true;
    ConsumeToken();
  }
  return false;
}

static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) {
  return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;
}

bool Parser::SkipAnyUntil(tok::TokenKind T, SkipUntilFlags Flags){
  const PreprocessorLexer *L = PP.getCurrentFileLexer();
  while(1){
    if(Tok.is(T)){
      if (HasFlagsSet(Flags, StopBeforeMatch)) {
        // Noop, don't consume the token.
      } else {
        ConsumeAnyToken();
      }
      return true;
    }
    else if(PP.getCurrentFileLexer() != L){
      return false;
    }

    ConsumeAnyToken();
  }
}

//
// you may get Actions.getASTContext().
//
std::string get_string(const Expr *expr, const ASTContext &Context) {
  PrintingPolicy print_policy(Context.getLangOpts());
  print_policy.FullyQualifiedName = 1;
  print_policy.SuppressScope = 0;
  print_policy.SuppressUnwrittenScope = 0;
  std::string expr_string;
  llvm::raw_string_ostream stream(expr_string);
  expr->printPretty(stream, nullptr, print_policy);
  stream.flush();
  return expr_string;
}

std::string get_string(const Stmt *expr, const ASTContext &Context) {
  PrintingPolicy print_policy(Context.getLangOpts());
  print_policy.FullyQualifiedName = 1;
  print_policy.SuppressScope = 0;
  print_policy.SuppressUnwrittenScope = 0;
  std::string expr_string;
  llvm::raw_string_ostream stream(expr_string);
  expr->printPretty(stream, nullptr, print_policy);
  stream.flush();
  return expr_string;
}

#endif