view tools/clang/lib/Parse/ParseCbC.cpp @ 42:3e178477409f

made some submethods for the methods which emit CbC statements.
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Fri, 27 Dec 2013 00:08:21 +0900
parents 1d6c745cd57d
children 7116d17d6428
line wrap: on
line source

#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"
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;
};
}

StmtResult Parser::Create__returnStmt(){
  SourceLocation Loc = Tok.getLocation();
  ParsedAttributesWithRange __retAttrs(AttrFactory);
  SourceLocation DeclStart = Loc, DeclEnd = Loc;
  ParsingDeclSpec PDS(*this);
  DeclSpec &__retDS = PDS;
  const char *PrevSpec = 0;
  unsigned DiagID = 0;
  bool isInvalid = false;
  if (__retDS.getSourceRange().isInvalid()) {
    __retDS.SetRangeStart(Loc);
    __retDS.SetRangeEnd(Loc);
  }
  isInvalid = __retDS.SetTypeSpecType(DeclSpec::TST___code, Loc, PrevSpec, DiagID);
  if (isInvalid) {
    assert(PrevSpec && "Method did not return previous specifier!");
    assert(DiagID);
    if (DiagID == diag::ext_duplicate_declspec)
      Diag(Tok, DiagID)
	<< PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
    else
      Diag(Tok, DiagID) << PrevSpec;
  }
  __retDS.SetRangeEnd(Loc);
  __retDS.Finish(Diags, PP);
  ParsingDeclarator D(*this, PDS, static_cast<Declarator::TheContext>(Declarator::BlockContext));
  D.setEllipsisLoc(SourceLocation());
  bool hadGroupingParens = D.hasGroupingParens();
  D.setGroupingParens(true);
  IdentifierInfo* II = CreateIdentifierInfo("__CbC_return",12, Loc); // CreateIdentifierInfo(name,length of the name, SourceLocation);
  D.SetRangeEnd(Loc);
  DeclSpec DS(AttrFactory);

  DS.Finish(Diags, PP);
  D.SetIdentifier(II, Loc);
  
  D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,DS.getConstSpecLoc(),DS.getVolatileSpecLoc(),
					    DS.getRestrictSpecLoc()),DS.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 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;
  D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,false,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();
  
  SmallVector<Decl *, 8> DeclsInGroup;
  Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
  D.complete(FirstDecl);
  DeclsInGroup.push_back(FirstDecl);
  
  DeclGroupPtrTy __retDecl = Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
  return Actions.ActOnDeclStmt(__retDecl, DeclStart, DeclEnd);
}

StmtResult Parser::CreateReturnAssignmentStmt(){
  ExprResult Res,LHS,RHS;
  Token LHSToken,Next;
  IdentifierInfo *II;
  SourceLocation Loc = Tok.getLocation();
  CXXScopeSpec SS;
  II = CreateIdentifierInfo("__CbC_return", 12, Loc);
  Next.startToken();
  Next.setLocation(Loc);
  Next.setKind(tok::equal);
  LHSToken.startToken();
  LHSToken.setLocation(Loc);
  LHSToken.setLength(II->getLength());
  LHSToken.setIdentifierInfo(II);
  LHSToken.setKind(tok::identifier);

  ExternalSpace::StatementFilterCCC Validator(Next);
  Sema::NameClassification Classification = Actions.ClassifyName(getCurScope(), SS, II, Loc, Next, false, SS.isEmpty() ? &Validator : 0);

  LHSToken.setKind(tok::annot_primary_expr);
  setExprAnnotation(LHSToken, Classification.getExpression());
  LHSToken.setAnnotationEndLoc(Loc);
  PP.AnnotateCachedTokens(LHSToken);
  LHS = getExprAnnotation(LHSToken);
  RHS = LookupAndDeclareName(CreateIdentifierInfo("return1", 7, Loc));
  Res = Actions.CreateBuiltinBinOp(Loc, BO_Assign, LHS.take(), RHS.take());
  return Actions.ActOnExprStmt(Res);
}


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",6,Loc));
  ExprVector ArgExprs;
  ExprResult __envExprRes = CondExp.get();

  __envExprRes = LookupAndDeclareName(CreateIdentifierInfo("__CbC_environment", 17, Loc));
  __envExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo("env", 3, 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(),Tok.getLocation(),"in create setjmp statement for CbC");
  StmtVector innerStmts;
  StmtResult innerStmtRes;
  ExprResult innerExprRes;
  DeclSpec CastDS(AttrFactory);
						      
  if (CastDS.getSourceRange().isInvalid()) {
    CastDS.SetRangeStart(Loc);
    CastDS.SetRangeEnd(Loc);
  }
  ParsedAttributesWithRange attrs(AttrFactory);
  bool isInvalid = false;
  const char *PrevSpec = 0;
  unsigned DiagID = 0;
  isInvalid = CastDS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
  CastDS.SetRangeEnd(Tok.getLocation());
  isInvalid = false;
  DiagID = 0;
  ProhibitAttributes(attrs);
  CastDS.Finish(Diags, PP);

  Declarator CastDeclaratorInfo(CastDS, Declarator::TypeNameContext);
  CastDeclaratorInfo.SetRangeEnd(Loc);
  DeclSpec pointerDS(AttrFactory);
  pointerDS.Finish(Diags, PP);
  DeclaratorScopeObj DeclScopeObj(*this, CastDeclaratorInfo.getCXXScopeSpec());
  CastDeclaratorInfo.SetIdentifier(0, Loc);
  CastDeclaratorInfo.AddTypeInfo(DeclaratorChunk::getPointer(pointerDS.getTypeQualifiers(), Loc, 
							     pointerDS.getConstSpecLoc(), 
							     pointerDS.getVolatileSpecLoc(),
							     pointerDS.getRestrictSpecLoc()),
				 pointerDS.getAttributes(),SourceLocation());

  innerExprRes = LookupAndDeclareName(CreateIdentifierInfo("__CbC_environment", 17, Loc));
  innerExprRes = LookupMemberAndBuildExpr(CreateIdentifierInfo("ret_p",5,Loc), innerExprRes.take(), false);
  Expr *CastExpr = innerExprRes.take();
  TypeSourceInfo *castTInfo = Actions.GetTypeForDeclaratorCast(CastDeclaratorInfo, CastExpr->getType());
  Actions.checkUnusedDeclAttributes(CastDeclaratorInfo);

  innerExprRes = Actions.BuildCStyleCastExpr(Loc, castTInfo, Loc, CastExpr);
  innerExprRes = Actions.ActOnParenExpr(Loc, Loc, innerExprRes.take());
  innerExprRes = Actions.ActOnUnaryOp(getCurScope(), Loc, tok::star, innerExprRes.get());
  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);
  Name.setIdentifier(II, Loc);
  TemplateArgumentListInfo TemplateArgsBuffer;
  DeclarationNameInfo NameInfo;
  const TemplateArgumentListInfo *TemplateArgs;
  Actions.DecomposeUnqualifiedId(Name, TemplateArgsBuffer, NameInfo, TemplateArgs);
  DeclarationName DName = NameInfo.getName();
  II = DName.getAsIdentifierInfo();
  SourceLocation NameLoc = NameInfo.getLoc();
  LookupResult R(Actions, NameInfo,Actions.LookupOrdinaryName);
  Actions.LookupParsedName(R, getCurScope(), &SS, true);

  if (II && R.empty()) {
    NamedDecl *D = Actions.ImplicitlyDefineFunction(NameLoc, *II, getCurScope());
    if (D) R.addDecl(D);
  }
  return Actions.BuildDeclarationNameExpr(SS, R, false);
}

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);

}