Example #1
0
ExprResult Parser::ParseExpectedConditionExpression(const char *DiagAfter) {
  if (!ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
      DiagAfter))
    return ExprError();
  ExprResult Condition = ParseExpectedFollowupExpression("(");
  if(Condition.isInvalid()) return Condition;
  if (!ExpectAndConsume(tok::r_paren))
    return ExprError();
  return Condition;
}
Example #2
0
/// ParseDesignator - Parse a designator. Return null if current token is not a
/// designator.
///
///   [R601]:
///     designator :=
///         object-name
///      or array-element
///      or array-section
///      or coindexed-named-object
///      or complex-part-designator
///      or structure-component
///      or substring
///
/// FIXME: substring for a character array
ExprResult Parser::ParseDesignator(bool IsLvalue) {
  auto E = ParseNameOrCall();

  struct ScopedFlag {
    bool value;
    bool &dest;

    ScopedFlag(bool &flag) : dest(flag) {
      value = flag;
    }
    ~ScopedFlag() {
      dest = value;
    }
  };

  ScopedFlag Flag(DontResolveIdentifiers);
  if(DontResolveIdentifiersInSubExpressions)
    DontResolveIdentifiers = true;

  while(true) {
    if(!E.isUsable())
      break;
    if(IsPresent(tok::l_paren)) {
      auto EType = E.get()->getType();
      if(EType->isArrayType())
        E = ParseArraySubscript(E);
      else if(EType->isCharacterType())
        E = ParseSubstring(E);
      else {
        Diag.Report(Tok.getLocation(), diag::err_unexpected_lparen);
        return ExprError();
      }
    } else if(IsPresent(tok::percent)) {
      auto EType = E.get()->getType();
      if(EType->isRecordType())
        E = ParseStructureComponent(E);
      else {
        Diag.Report(Tok.getLocation(), diag::err_unexpected_percent);
        return ExprError();
      }
    } else if(IsPresent(tok::period)) {
      auto EType = E.get()->getType();
      if(EType->isRecordType())
        E = ParseStructureComponent(E);
      else {
        Diag.Report(Tok.getLocation(), diag::err_unexpected_period);
        return ExprError();
      }
    }
    else break;
  }

  return E;
}
Example #3
0
File: PQL.cpp Project: jonasfj/PeTe
void AssignmentExpression::analyze(AnalysisContext& context){
	for(iter it = assignments.begin(); it != assignments.end(); it++){
		AnalysisContext::ResolutionResult result = context.resolve(it->identifier);
		if(result.success && !result.isPlace){
			it->offset = result.offset;
		}else if(result.isPlace){
			context.reportError(ExprError("You cannot assign to an place!"));
		}else{
			context.reportError(ExprError("Variable for assignment could not be resolved!"));
		}
		it->expr->analyze(context);
	}
}
Example #4
0
ExprResult Parser::ParseRecursiveCallExpression(SourceRange IDRange) {
  auto Func = Actions.CurrentContextAsFunction();
  auto IDLoc = IDRange.Start;
  if(Func->isSubroutine()) {
    Diag.Report(IDLoc, diag::err_invalid_subroutine_use)
     << Func->getIdentifier() << getTokenRange(IDLoc);
    return ExprError();
  }
  if(!Actions.CheckRecursiveFunction(IDLoc))
    return ExprError();

  if(!IsPresent(tok::l_paren))
    return FunctionRefExpr::Create(Context, IDRange, Func);
  return ParseCallExpression(IDLoc, Func);
}
Example #5
0
ExprResult Parser::ParseExpectedExpression() {
  if(Tok.isAtStartOfStatement()) {
    Diag.Report(getExpectedLoc(), diag::err_expected_expression);
    return ExprError();
  }
  return ParseExpression();
}
Example #6
0
ExprResult Sema::ActOnDATAConstantExpr(ASTContext &C,
                                       SourceLocation RepeatLoc,
                                       ExprResult RepeatCount,
                                       ExprResult Value) {
  IntegerConstantExpr *RepeatExpr = nullptr;
  bool HasErrors = false;

  if(RepeatCount.isUsable()) {
    RepeatExpr = dyn_cast<IntegerConstantExpr>(RepeatCount.get());
    if(!RepeatExpr ||
       !RepeatExpr->getValue().isStrictlyPositive()) {
      Diags.Report(RepeatCount.get()->getLocation(),
                   diag::err_expected_integer_gt_0)
        << RepeatCount.get()->getSourceRange();
      HasErrors = true;
      RepeatExpr = nullptr;
    }
  }

  if(!CheckConstantExpression(Value.get()))
    HasErrors = true;

  if(HasErrors) return ExprError();
  return RepeatExpr? RepeatedConstantExpr::Create(C, RepeatLoc,
                                                  RepeatExpr, Value.take())
                   : Value;
}
Example #7
0
/// \brief Looks at the next token to see if it's an expression
/// and calls ParseExpression if it is, or reports an expected expression
/// error.
ExprResult Parser::ParseExpectedFollowupExpression(const char *DiagAfter) {
  if(Tok.isAtStartOfStatement()) {
    Diag.Report(getExpectedLoc(), diag::err_expected_expression_after)
      << DiagAfter;
    return ExprError();
  }
  return ParseExpression();
}
Example #8
0
/// ParseTypeConstructorExpression - Parses a type constructor.
ExprResult Parser::ParseTypeConstructor(SourceLocation IDLoc, RecordDecl *Record) {
  SmallVector<Expr*, 8> Arguments;
  SourceLocation RParenLoc = IDLoc;
  auto LParenLoc = Tok.getLocation();
  auto E = ParseFunctionCallArgumentList(Arguments, RParenLoc);
  if(E.isInvalid())
    return ExprError();
  return Actions.ActOnTypeConstructorExpr(Context, IDLoc, LParenLoc, RParenLoc, Record, Arguments);
}
Example #9
0
/// ParseStructureComponent - Parse a structure component.
///
///   R613:
///     structure-component :=
///        designator % data-ref
ExprResult Parser::ParseStructureComponent(ExprResult Target) {
  auto Loc = ConsumeToken();
  auto ID = Tok.getIdentifierInfo();
  auto IDLoc = Tok.getLocation();
  if(!ExpectAndConsume(tok::identifier))
    return ExprError();
  return Actions.ActOnStructureComponentExpr(Context, Loc, IDLoc, ID,
                                             Target.get());
}
Example #10
0
/// ParseCallExpression - Parse a call expression
ExprResult Parser::ParseCallExpression(SourceLocation IDLoc, FunctionDecl *Function) {
  SmallVector<Expr*, 8> Arguments;
  auto Loc = Tok.getLocation();
  SourceLocation RParenLoc = Loc;
  auto Result = ParseFunctionCallArgumentList(Arguments, RParenLoc);
  if(Result.isInvalid())
    return ExprError();
  return Actions.ActOnCallExpr(Context, Loc, RParenLoc, IDLoc, Function, Arguments);
}
Example #11
0
/// Parse the optional KIND or LEN selector.
/// 
///   [R405]:
///     kind-selector :=
///         ( [ KIND = ] scalar-int-initialization-expr )
///   [R425]:
///     length-selector :=
///         ( [ LEN = ] type-param-value )
ExprResult Parser::ParseSelector(bool IsKindSel) {
  if (ConsumeIfPresent(IsKindSel ? tok::kw_KIND : tok::kw_LEN)) {
    if (!ExpectAndConsume(tok::equal))
      return ExprError();
    // TODO: We have a "REAL (KIND(10D0)) :: x" situation.
  }

  return ParseExpression();
}
Example #12
0
/// ParseFunctionCallArgumentList - Parses an argument list to a call expression.
ExprResult Parser::ParseFunctionCallArgumentList(SmallVectorImpl<Expr*> &Args, SourceLocation &RParenLoc) {
  if(!ExpectAndConsume(tok::l_paren))
    return ExprError();

  RParenLoc = getExpectedLoc();
  if(ConsumeIfPresent(tok::r_paren))
    return ExprResult();

  auto PunctuationTok = "(";
  do {
    if(Tok.isAtStartOfStatement())
      break;
    auto E = ParseExpectedFollowupExpression(PunctuationTok);
    if(E.isInvalid())
      SkipUntil(tok::comma, tok::r_paren, true, true);
    else Args.push_back(E.get());
    PunctuationTok = ",";
  } while (ConsumeIfPresent(tok::comma));

  RParenLoc = getExpectedLoc();
  ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren);
  return ExprResult();
}
Example #13
0
/// ParseNameOrCall - Parse a name or a call expression
ExprResult Parser::ParseNameOrCall() {
  auto IDInfo = Tok.getIdentifierInfo();
  assert(IDInfo && "Token isn't an identifier");
  auto IDRange = getTokenRange();
  auto IDLoc = ConsumeToken();

  if(DontResolveIdentifiers)
    return UnresolvedIdentifierExpr::Create(Context,
                                            IDRange, IDInfo);

  // [R504]:
  //   object-name :=
  //       name
  auto Declaration = Actions.ResolveIdentifier(IDInfo);
  if(!Declaration) {
    if(IsPresent(tok::l_paren))
      Declaration = Actions.ActOnImplicitFunctionDecl(Context, IDLoc, IDInfo);
    else
      Declaration = Actions.ActOnImplicitEntityDecl(Context, IDLoc, IDInfo);
    if(!Declaration)
      return ExprError();
  } else {
    // INTEGER f
    // X = f(10) <-- implicit function declaration.
    if(IsPresent(tok::l_paren))
      Declaration = Actions.ActOnPossibleImplicitFunctionDecl(Context, IDLoc, IDInfo, Declaration);
  }

  if(VarDecl *VD = dyn_cast<VarDecl>(Declaration)) {
    // FIXME: function returing array
    if(IsPresent(tok::l_paren) &&
       VD->isFunctionResult() && isa<FunctionDecl>(Actions.CurContext)) {
      // FIXME: accessing function results from inner recursive functions
      return ParseRecursiveCallExpression(IDRange);
    }
    // the VarDecl is obtained from a NamedDecl which does not have a type
    // apply implicit typing rules in case VD does not have a type
    // FIXME: there should be a way to avoid re-applying the implicit rules
    // by returning a VarDecl instead of a NamedDecl when looking up a name in
    // the scope
    if (VD->getType().isNull()) Actions.ApplyImplicitRulesToArgument(VD,IDRange);
    return VarExpr::Create(Context, IDRange, VD);
  }
  else if(IntrinsicFunctionDecl *IFunc = dyn_cast<IntrinsicFunctionDecl>(Declaration)) {
    SmallVector<Expr*, 8> Arguments;
    SourceLocation RParenLoc = Tok.getLocation();
    auto Result = ParseFunctionCallArgumentList(Arguments, RParenLoc);
    if(Result.isInvalid())
      return ExprError();
    return Actions.ActOnIntrinsicFunctionCallExpr(Context, IDLoc, IFunc, Arguments);
  } else if(FunctionDecl *Func = dyn_cast<FunctionDecl>(Declaration)) {
    // FIXME: allow subroutines, but errors in sema
    if(!IsPresent(tok::l_paren))
      return FunctionRefExpr::Create(Context, IDRange, Func);
    if(!Func->isSubroutine()) {
      return ParseCallExpression(IDLoc, Func);
    }
  } else if(isa<SelfDecl>(Declaration) && isa<FunctionDecl>(Actions.CurContext))
    return ParseRecursiveCallExpression(IDRange);
  else if(auto Record = dyn_cast<RecordDecl>(Declaration))
    return ParseTypeConstructor(IDLoc, Record);
  Diag.Report(IDLoc, diag::err_expected_var);
  return ExprError();
}
Example #14
0
// ParsePrimaryExpr - Parse a primary expression.
//
//   [R701]:
//     primary :=
//         constant
//      or designator
//      or array-constructor
//      or structure-constructor
//      or function-reference
//      or type-param-inquiry
//      or type-param-name
//      or ( expr )
Parser::ExprResult Parser::ParsePrimaryExpr(bool IsLvalue) {
  ExprResult E;
  SourceLocation Loc = Tok.getLocation();

  // FIXME: Add rest of the primary expressions.
  switch (Tok.getKind()) {
  default:
    if (isTokenIdentifier())
      goto possible_keyword_as_ident;
    Diag.Report(getExpectedLoc(), diag::err_expected_expression);
    return ExprError();
  case tok::error:
    Lex();
    return ExprError();
  case tok::l_paren: {
    ConsumeParen();

    E = ParseExpression();
    // complex constant.
    if(ConsumeIfPresent(tok::comma)) {
      if(E.isInvalid()) return E;
      auto ImPart = ParseExpectedFollowupExpression(",");
      if(ImPart.isInvalid()) return ImPart;
      E = Actions.ActOnComplexConstantExpr(Context, Loc,
                                           getMaxLocationOfCurrentToken(),
                                           E, ImPart);
    }

    ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren);
    break;
  }
  case tok::l_parenslash : {
    return ParseArrayConstructor();
    break;
  }
  case tok::logical_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = LogicalConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first, Context.LogicalTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::binary_boz_constant:
  case tok::octal_boz_constant:
  case tok::hex_boz_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = BOZConstantExpr::Create(Context, Loc,
                                getMaxLocationOfCurrentToken(),
                                StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::char_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    E = CharacterConstantExpr::Create(Context, getTokenRange(),
                                      StringRef(NumStr), Context.CharacterTy);
    ConsumeToken();
    // Possible substring
    if(IsPresent(tok::l_paren))
      return ParseSubstring(E);
    break;
  }
  case tok::int_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = IntegerConstantExpr::Create(Context, getTokenRange(),
                                    StrPair.first);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);

    Lex();
    break;
  }
  case tok::real_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.RealTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::double_precision_literal_constant: {
    std::string NumStr;
    CleanLiteral(Tok, NumStr);
    // Replace the d/D exponent into e exponent
    for(size_t I = 0, Len = NumStr.length(); I < Len; ++I) {
      if(NumStr[I] == 'd' || NumStr[I] == 'D') {
        NumStr[I] = 'e';
        break;
      } else if(NumStr[I] == '_') break;
    }

    StringRef Data(NumStr);
    std::pair<StringRef, StringRef> StrPair = Data.split('_');
    E = RealConstantExpr::Create(Context, getTokenRange(),
                                 NumStr, Context.DoublePrecisionTy);
    SetKindSelector(cast<ConstantExpr>(E.get()), StrPair.second);
    ConsumeToken();
    break;
  }
  case tok::identifier:
    possible_keyword_as_ident:
    E = Parser::ParseDesignator(IsLvalue);
    if (E.isInvalid()) return E;
    break;
  case tok::minus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Minus, E);
    break;
  case tok::plus:
    Lex();
    E = Parser::ParsePrimaryExpr();
    if (E.isInvalid()) return E;
    E = Actions.ActOnUnaryExpr(Context, Loc, UnaryExpr::Plus, E);
    break;
  }

  return E;
}