当前位置: 首页>>代码示例>>C++>>正文


C++ TypeResult::get方法代码示例

本文整理汇总了C++中TypeResult::get方法的典型用法代码示例。如果您正苦于以下问题:C++ TypeResult::get方法的具体用法?C++ TypeResult::get怎么用?C++ TypeResult::get使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在TypeResult的用法示例。


在下文中一共展示了TypeResult::get方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: AnnotateTemplateIdTokenAsType

/// \brief Replaces a template-id annotation token with a type
/// annotation token.
///
/// If there was a failure when forming the type from the template-id,
/// a type annotation token will still be created, but will have a
/// NULL type pointer to signify an error.
void Parser::AnnotateTemplateIdTokenAsType() {
  assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");

  TemplateIdAnnotation *TemplateId
    = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
  assert((TemplateId->Kind == TNK_Type_template ||
          TemplateId->Kind == TNK_Dependent_template_name) &&
         "Only works for type and dependent templates");

  ASTTemplateArgsPtr TemplateArgsPtr(Actions,
                                     TemplateId->getTemplateArgs(),
                                     TemplateId->NumArgs);

  TypeResult Type
    = Actions.ActOnTemplateIdType(TemplateId->SS,
                                  TemplateId->Template,
                                  TemplateId->TemplateNameLoc,
                                  TemplateId->LAngleLoc,
                                  TemplateArgsPtr,
                                  TemplateId->RAngleLoc);
  // Create the new "type" annotation token.
  Tok.setKind(tok::annot_typename);
  setTypeAnnotation(Tok, Type.isInvalid() ? ParsedType() : Type.get());
  if (TemplateId->SS.isNotEmpty()) // it was a C++ qualified type name.
    Tok.setLocation(TemplateId->SS.getBeginLoc());
  // End location stays the same

  // Replace the template-id annotation token, and possible the scope-specifier
  // that precedes it, with the typename annotation token.
  PP.AnnotateCachedTokens(Tok);
  TemplateId->Destroy();
}
开发者ID:5432935,项目名称:crossbridge,代码行数:38,代码来源:ParseTemplate.cpp

示例2: ParseTemplateArgument

/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
///
///       template-argument: [C++ 14.2]
///         constant-expression
///         type-id
///         id-expression
ParsedTemplateArgument Parser::ParseTemplateArgument() {
  // C++ [temp.arg]p2:
  //   In a template-argument, an ambiguity between a type-id and an
  //   expression is resolved to a type-id, regardless of the form of
  //   the corresponding template-parameter.
  //
  // Therefore, we initially try to parse a type-id.  
  if (isCXXTypeId(TypeIdAsTemplateArgument)) {
    SourceLocation Loc = Tok.getLocation();
    TypeResult TypeArg = ParseTypeName(/*Range=*/0, 
                                       Declarator::TemplateTypeArgContext);
    if (TypeArg.isInvalid())
      return ParsedTemplateArgument();
    
    return ParsedTemplateArgument(ParsedTemplateArgument::Type,
                                  TypeArg.get().getAsOpaquePtr(), 
                                  Loc);
  }
  
  // Try to parse a template template argument.
  {
    TentativeParsingAction TPA(*this);

    ParsedTemplateArgument TemplateTemplateArgument
      = ParseTemplateTemplateArgument();
    if (!TemplateTemplateArgument.isInvalid()) {
      TPA.Commit();
      return TemplateTemplateArgument;
    }
    
    // Revert this tentative parse to parse a non-type template argument.
    TPA.Revert();
  }
  
  // Parse a non-type template argument. 
  SourceLocation Loc = Tok.getLocation();
  ExprResult ExprArg = ParseConstantExpression();
  if (ExprArg.isInvalid() || !ExprArg.get())
    return ParsedTemplateArgument();

  return ParsedTemplateArgument(ParsedTemplateArgument::NonType, 
                                ExprArg.release(), Loc);
}
开发者ID:5432935,项目名称:crossbridge,代码行数:49,代码来源:ParseTemplate.cpp

示例3: ParsedTemplateArgument

ParsedTemplateArgument 
Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
                         SourceLocation EllipsisLoc) {
  if (Arg.isInvalid())
    return Arg;

  switch (Arg.getKind()) {
  case ParsedTemplateArgument::Type: {
    TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
    if (Result.isInvalid())
      return ParsedTemplateArgument();

    return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(), 
                                  Arg.getLocation());
  }

  case ParsedTemplateArgument::NonType: {
    ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
    if (Result.isInvalid())
      return ParsedTemplateArgument();
    
    return ParsedTemplateArgument(Arg.getKind(), Result.get(), 
                                  Arg.getLocation());
  }
    
  case ParsedTemplateArgument::Template:
    if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
      SourceRange R(Arg.getLocation());
      if (Arg.getScopeSpec().isValid())
        R.setBegin(Arg.getScopeSpec().getBeginLoc());
      Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
        << R;
      return ParsedTemplateArgument();
    }
      
    return Arg.getTemplatePackExpansion(EllipsisLoc);
  }
  llvm_unreachable("Unhandled template argument kind?");
  return ParsedTemplateArgument();
}
开发者ID:ACSOP,项目名称:android_external_clang,代码行数:40,代码来源:SemaTemplateVariadic.cpp

示例4: getFunction

/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
/// "TheDeclarator" is the declarator that this will be added to.
DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
                                             bool isAmbiguous,
                                             SourceLocation LParenLoc,
                                             ParamInfo *Params,
                                             unsigned NumParams,
                                             SourceLocation EllipsisLoc,
                                             SourceLocation RParenLoc,
                                             unsigned TypeQuals,
                                             bool RefQualifierIsLvalueRef,
                                             SourceLocation RefQualifierLoc,
                                             SourceLocation ConstQualifierLoc,
                                             SourceLocation
                                                 VolatileQualifierLoc,
                                             SourceLocation
                                                 RestrictQualifierLoc,
                                             SourceLocation MutableLoc,
                                             ExceptionSpecificationType
                                                 ESpecType,
                                             SourceLocation ESpecLoc,
                                             ParsedType *Exceptions,
                                             SourceRange *ExceptionRanges,
                                             unsigned NumExceptions,
                                             Expr *NoexceptExpr,
                                             CachedTokens *ExceptionSpecTokens,
                                             SourceLocation LocalRangeBegin,
                                             SourceLocation LocalRangeEnd,
                                             Declarator &TheDeclarator,
                                             TypeResult TrailingReturnType) {
  assert(!(TypeQuals & DeclSpec::TQ_atomic) &&
         "function cannot have _Atomic qualifier");

  DeclaratorChunk I;
  I.Kind                        = Function;
  I.Loc                         = LocalRangeBegin;
  I.EndLoc                      = LocalRangeEnd;
  I.Fun.AttrList                = nullptr;
  I.Fun.hasPrototype            = hasProto;
  I.Fun.isVariadic              = EllipsisLoc.isValid();
  I.Fun.isAmbiguous             = isAmbiguous;
  I.Fun.LParenLoc               = LParenLoc.getRawEncoding();
  I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
  I.Fun.RParenLoc               = RParenLoc.getRawEncoding();
  I.Fun.DeleteParams            = false;
  I.Fun.TypeQuals               = TypeQuals;
  I.Fun.NumParams               = NumParams;
  I.Fun.Params                  = nullptr;
  I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
  I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
  I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
  I.Fun.VolatileQualifierLoc    = VolatileQualifierLoc.getRawEncoding();
  I.Fun.RestrictQualifierLoc    = RestrictQualifierLoc.getRawEncoding();
  I.Fun.MutableLoc              = MutableLoc.getRawEncoding();
  I.Fun.ExceptionSpecType       = ESpecType;
  I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
  I.Fun.NumExceptions           = 0;
  I.Fun.Exceptions              = nullptr;
  I.Fun.NoexceptExpr            = nullptr;
  I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
                                  TrailingReturnType.isInvalid();
  I.Fun.TrailingReturnType      = TrailingReturnType.get();

  assert(I.Fun.TypeQuals == TypeQuals && "bitfield overflow");
  assert(I.Fun.ExceptionSpecType == ESpecType && "bitfield overflow");

  // new[] a parameter array if needed.
  if (NumParams) {
    // If the 'InlineParams' in Declarator is unused and big enough, put our
    // parameter list there (in an effort to avoid new/delete traffic).  If it
    // is already used (consider a function returning a function pointer) or too
    // small (function with too many parameters), go to the heap.
    if (!TheDeclarator.InlineParamsUsed &&
        NumParams <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
      I.Fun.Params = TheDeclarator.InlineParams;
      I.Fun.DeleteParams = false;
      TheDeclarator.InlineParamsUsed = true;
    } else {
      I.Fun.Params = new DeclaratorChunk::ParamInfo[NumParams];
      I.Fun.DeleteParams = true;
    }
    memcpy(I.Fun.Params, Params, sizeof(Params[0]) * NumParams);
  }

  // Check what exception specification information we should actually store.
  switch (ESpecType) {
  default: break; // By default, save nothing.
  case EST_Dynamic:
    // new[] an exception array if needed
    if (NumExceptions) {
      I.Fun.NumExceptions = NumExceptions;
      I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
      for (unsigned i = 0; i != NumExceptions; ++i) {
        I.Fun.Exceptions[i].Ty = Exceptions[i];
        I.Fun.Exceptions[i].Range = ExceptionRanges[i];
      }
    }
    break;

  case EST_ComputedNoexcept:
//.........这里部分代码省略.........
开发者ID:apurtell,项目名称:llvm-clang,代码行数:101,代码来源:DeclSpec.cpp

示例5: ParseInitializerWithPotentialDesignator

/// ParseInitializerWithPotentialDesignator - Parse the 'initializer' production
/// checking to see if the token stream starts with a designator.
///
///       designation:
///         designator-list '='
/// [GNU]   array-designator
/// [GNU]   identifier ':'
///
///       designator-list:
///         designator
///         designator-list designator
///
///       designator:
///         array-designator
///         '.' identifier
///
///       array-designator:
///         '[' constant-expression ']'
/// [GNU]   '[' constant-expression '...' constant-expression ']'
///
/// NOTE: [OBC] allows '[ objc-receiver objc-message-args ]' as an
/// initializer (because it is an expression).  We need to consider this case
/// when parsing array designators.
///
ExprResult Parser::ParseInitializerWithPotentialDesignator() {

  // If this is the old-style GNU extension:
  //   designation ::= identifier ':'
  // Handle it as a field designator.  Otherwise, this must be the start of a
  // normal expression.
  if (Tok.is(tok::identifier)) {
    const IdentifierInfo *FieldName = Tok.getIdentifierInfo();

    SmallString<256> NewSyntax;
    llvm::raw_svector_ostream(NewSyntax) << '.' << FieldName->getName()
                                         << " = ";

    SourceLocation NameLoc = ConsumeToken(); // Eat the identifier.

    assert(Tok.is(tok::colon) && "MayBeDesignationStart not working properly!");
    SourceLocation ColonLoc = ConsumeToken();

    Diag(NameLoc, diag::ext_gnu_old_style_field_designator)
      << FixItHint::CreateReplacement(SourceRange(NameLoc, ColonLoc),
                                      NewSyntax);

    Designation D;
    D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
    return Actions.ActOnDesignatedInitializer(D, ColonLoc, true,
                                              ParseInitializer());
  }

  // Desig - This is initialized when we see our first designator.  We may have
  // an objc message send with no designator, so we don't want to create this
  // eagerly.
  Designation Desig;

  // Parse each designator in the designator list until we find an initializer.
  while (Tok.is(tok::period) || Tok.is(tok::l_square)) {
    if (Tok.is(tok::period)) {
      // designator: '.' identifier
      SourceLocation DotLoc = ConsumeToken();

      if (Tok.isNot(tok::identifier)) {
        Diag(Tok.getLocation(), diag::err_expected_field_designator);
        return ExprError();
      }

      Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc,
                                               Tok.getLocation()));
      ConsumeToken(); // Eat the identifier.
      continue;
    }

    // We must have either an array designator now or an objc message send.
    assert(Tok.is(tok::l_square) && "Unexpected token!");

    // Handle the two forms of array designator:
    //   array-designator: '[' constant-expression ']'
    //   array-designator: '[' constant-expression '...' constant-expression ']'
    //
    // Also, we have to handle the case where the expression after the
    // designator an an objc message send: '[' objc-message-expr ']'.
    // Interesting cases are:
    //   [foo bar]         -> objc message send
    //   [foo]             -> array designator
    //   [foo ... bar]     -> array designator
    //   [4][foo bar]      -> obsolete GNU designation with objc message send.
    //
    // We do not need to check for an expression starting with [[ here. If it
    // contains an Objective-C message send, then it is not an ill-formed
    // attribute. If it is a lambda-expression within an array-designator, then
    // it will be rejected because a constant-expression cannot begin with a
    // lambda-expression.
    InMessageExpressionRAIIObject InMessage(*this, true);

    BalancedDelimiterTracker T(*this, tok::l_square);
    T.consumeOpen();
    SourceLocation StartLoc = T.getOpenLocation();

//.........这里部分代码省略.........
开发者ID:CTSRD-CHERI,项目名称:clang,代码行数:101,代码来源:ParseInit.cpp

示例6: AnnotateTemplateIdToken

/// \brief Replace the tokens that form a simple-template-id with an
/// annotation token containing the complete template-id.
///
/// The first token in the stream must be the name of a template that
/// is followed by a '<'. This routine will parse the complete
/// simple-template-id and replace the tokens with a single annotation
/// token with one of two different kinds: if the template-id names a
/// type (and \p AllowTypeAnnotation is true), the annotation token is
/// a type annotation that includes the optional nested-name-specifier
/// (\p SS). Otherwise, the annotation token is a template-id
/// annotation that does not include the optional
/// nested-name-specifier.
///
/// \param Template  the declaration of the template named by the first
/// token (an identifier), as returned from \c Action::isTemplateName().
///
/// \param TemplateNameKind the kind of template that \p Template
/// refers to, as returned from \c Action::isTemplateName().
///
/// \param SS if non-NULL, the nested-name-specifier that precedes
/// this template name.
///
/// \param TemplateKWLoc if valid, specifies that this template-id
/// annotation was preceded by the 'template' keyword and gives the
/// location of that keyword. If invalid (the default), then this
/// template-id was not preceded by a 'template' keyword.
///
/// \param AllowTypeAnnotation if true (the default), then a
/// simple-template-id that refers to a class template, template
/// template parameter, or other template that produces a type will be
/// replaced with a type annotation token. Otherwise, the
/// simple-template-id is always replaced with a template-id
/// annotation token.
///
/// If an unrecoverable parse error occurs and no annotation token can be
/// formed, this function returns true.
///
bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
                                     CXXScopeSpec &SS,
                                     UnqualifiedId &TemplateName,
                                     SourceLocation TemplateKWLoc,
                                     bool AllowTypeAnnotation) {
  assert(getLang().CPlusPlus && "Can only annotate template-ids in C++");
  assert(Template && Tok.is(tok::less) &&
         "Parser isn't at the beginning of a template-id");

  // Consume the template-name.
  SourceLocation TemplateNameLoc = TemplateName.getSourceRange().getBegin();

  // Parse the enclosed template argument list.
  SourceLocation LAngleLoc, RAngleLoc;
  TemplateArgList TemplateArgs;
  bool Invalid = ParseTemplateIdAfterTemplateName(Template, 
                                                  TemplateNameLoc,
                                                  SS, false, LAngleLoc,
                                                  TemplateArgs,
                                                  RAngleLoc);

  if (Invalid) {
    // If we failed to parse the template ID but skipped ahead to a >, we're not
    // going to be able to form a token annotation.  Eat the '>' if present.
    if (Tok.is(tok::greater))
      ConsumeToken();
    return true;
  }

  ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
                                     TemplateArgs.size());

  // Build the annotation token.
  if (TNK == TNK_Type_template && AllowTypeAnnotation) {
    TypeResult Type
      = Actions.ActOnTemplateIdType(SS, 
                                    Template, TemplateNameLoc,
                                    LAngleLoc, TemplateArgsPtr,
                                    RAngleLoc);
    if (Type.isInvalid()) {
      // If we failed to parse the template ID but skipped ahead to a >, we're not
      // going to be able to form a token annotation.  Eat the '>' if present.
      if (Tok.is(tok::greater))
        ConsumeToken();
      return true;
    }

    Tok.setKind(tok::annot_typename);
    setTypeAnnotation(Tok, Type.get());
    if (SS.isNotEmpty())
      Tok.setLocation(SS.getBeginLoc());
    else if (TemplateKWLoc.isValid())
      Tok.setLocation(TemplateKWLoc);
    else
      Tok.setLocation(TemplateNameLoc);
  } else {
    // Build a template-id annotation token that can be processed
    // later.
    Tok.setKind(tok::annot_template_id);
    TemplateIdAnnotation *TemplateId
      = TemplateIdAnnotation::Allocate(TemplateArgs.size());
    TemplateId->TemplateNameLoc = TemplateNameLoc;
    if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
//.........这里部分代码省略.........
开发者ID:5432935,项目名称:crossbridge,代码行数:101,代码来源:ParseTemplate.cpp

示例7: ParseParenExpr

/// ParseParenExpr - Parse a parenthesized expression with the given
/// \arg ExpectedType. \arg ExpectedType can be invalid if the type
/// cannot be inferred from the context.
///
/// paren-expr = '(' type number ')'
/// paren-expr = '(' identifier [type] expr+ ')
/// paren-expr = '(' ('Read' | 'ReadMSB' | 'ReadLSB') type expr update-list ')'
ExprResult ParserImpl::ParseParenExpr(TypeResult FIXME_UNUSED) {
  if (Tok.kind != Token::LParen) {
    Error("unexpected token.");
    ConsumeAnyToken();
    return ExprResult();
  }

  ConsumeLParen();
  
  // Check for coercion case (w32 11).
  if (Tok.kind == Token::KWWidth) {
    TypeResult ExpectedType = ParseTypeSpecifier();

    if (Tok.kind != Token::Number) {
      Error("coercion can only apply to a number.");
      SkipUntilRParen();
      return ExprResult();
    }
    
    // Make sure this was a type specifier we support.
    ExprResult Res;
    if (ExpectedType.isValid()) 
      Res = ParseNumber(ExpectedType.get());
    else
      ConsumeToken();

    ExpectRParen("unexpected argument in coercion.");  
    return Res;
  }
  
  if (Tok.kind != Token::Identifier) {
    Error("unexpected token, expected expression.");
    SkipUntilRParen();
    return ExprResult();
  }

  Token Name = Tok;
  ConsumeToken();

  // FIXME: Use invalid type (i.e. width==0)?
  Token TypeTok = Tok;
  bool HasType = TypeTok.kind == Token::KWWidth;
  TypeResult Type = HasType ? ParseTypeSpecifier() : Expr::Bool;

  // FIXME: For now just skip to rparen on error. It might be nice
  // to try and actually parse the child nodes though for error
  // messages & better recovery?
  if (!Type.isValid()) {
    SkipUntilRParen();
    return ExprResult();
  }
  Expr::Width ResTy = Type.get();

  unsigned ExprKind;
  bool IsFixed;
  int NumArgs;
  if (!LookupExprInfo(Name, ExprKind, IsFixed, NumArgs)) {
    // FIXME: For now just skip to rparen on error. It might be nice
    // to try and actually parse the child nodes though for error
    // messages & better recovery?
    Error("unknown expression kind.", Name);
    SkipUntilRParen();
    return ExprResult();
  }

  // See if we have to parse this form specially.
  if (NumArgs == -1) {
    switch (ExprKind) {
    case eMacroKind_Concat:
      return ParseConcatParenExpr(Name, ResTy);

    case Expr::Extract:
      return ParseExtractParenExpr(Name, ResTy);

    case eMacroKind_ReadLSB:
    case eMacroKind_ReadMSB:
    case Expr::Read:
      return ParseAnyReadParenExpr(Name, ExprKind, ResTy);

    default:
      Error("internal error, unimplemented special form.", Name);
      SkipUntilRParen();
      return ExprResult(Builder->Constant(0, ResTy));
    }
  }

  switch (NumArgs) {
  case 1:
    return ParseUnaryParenExpr(Name, ExprKind, IsFixed, ResTy);
  case 2:
    return ParseBinaryParenExpr(Name, ExprKind, IsFixed, ResTy);
  case 3:
    if (ExprKind == Expr::Select)
//.........这里部分代码省略.........
开发者ID:Himeshi,项目名称:klee,代码行数:101,代码来源:Parser.cpp

示例8: ParseExpr

/// ParseExpr - Parse an expression with the given \arg
/// ExpectedType. \arg ExpectedType can be invalid if the type cannot
/// be inferred from the context.
///
/// expr = false | true
/// expr = <constant>
/// expr = <identifier>
/// expr = [<identifier>:] paren-expr
ExprResult ParserImpl::ParseExpr(TypeResult ExpectedType) {
  // FIXME: Is it right to need to do this here?
  if (Tok.kind == Token::EndOfFile) {
    Error("unexpected end of file.");
    return ExprResult();
  }

  if (Tok.kind == Token::KWFalse || Tok.kind == Token::KWTrue) {
    bool Value = Tok.kind == Token::KWTrue;
    ConsumeToken();
    return ExprResult(Builder->Constant(Value, Expr::Bool));
  }
  
  if (Tok.kind == Token::Number) {
    if (!ExpectedType.isValid()) {
      Error("cannot infer type of number.");
      ConsumeToken();
      return ExprResult();
    }
    
    return ParseNumber(ExpectedType.get());
  }

  const Identifier *Label = 0;
  if (Tok.kind == Token::Identifier) {
    Token LTok = Tok;
    Label = GetOrCreateIdentifier(Tok);
    ConsumeToken();

    if (Tok.kind != Token::Colon) {
      ExprSymTabTy::iterator it = ExprSymTab.find(Label);

      if (it == ExprSymTab.end()) {
        Error("invalid expression label reference.", LTok);
        return ExprResult();
      }

      return it->second;
    }

    ConsumeToken();
    if (ExprSymTab.count(Label)) {
      Error("duplicate expression label definition.", LTok);
      Label = 0;
    }
  }

  Token Start = Tok;
  ExprResult Res = ParseParenExpr(ExpectedType);
  if (!Res.isValid()) {
    // If we know the type, define the identifier just so we don't get
    // use-of-undef errors. 
    // FIXME: Maybe we should let the symbol table map to invalid
    // entries?
    if (Label && ExpectedType.isValid()) {
      ref<Expr> Value = Builder->Constant(0, ExpectedType.get());
      ExprSymTab.insert(std::make_pair(Label, Value));
    }
    return Res;
  } else if (ExpectedType.isValid()) {
    // Type check result.    
    if (Res.get()->getWidth() != ExpectedType.get()) {
      // FIXME: Need more info, and range
      Error("expression has incorrect type.", Start);
      return ExprResult();
    }
  }

  if (Label)
    ExprSymTab.insert(std::make_pair(Label, Res.get()));
  return Res;
}
开发者ID:Himeshi,项目名称:klee,代码行数:80,代码来源:Parser.cpp

示例9: ParseArrayDecl

/// ParseArrayDecl - Parse an array declaration. The lexer should be positioned
/// at the opening 'array'.
///
/// array-declaration = "array" name "[" [ size ] "]" ":" domain "->" range 
///                       "=" array-initializer
/// array-initializer = "symbolic" | "{" { numeric-literal } "}"
DeclResult ParserImpl::ParseArrayDecl() {
  // FIXME: Recovery here is horrible, we need to scan to next decl start or
  // something.
  ConsumeExpectedToken(Token::KWArray);
  
  if (Tok.kind != Token::Identifier) {
    Error("expected identifier token.");
    return DeclResult();
  }

  Token Name = Tok;
  IntegerResult Size;
  TypeResult DomainType;
  TypeResult RangeType;
  std::vector< ref<ConstantExpr> > Values;

  ConsumeToken();
  
  if (Tok.kind != Token::LSquare) {
    Error("expected '['.");
    goto exit;
  }
  ConsumeLSquare();

  if (Tok.kind != Token::RSquare) {
    Size = ParseIntegerConstant(64);
  }
  if (Tok.kind != Token::RSquare) {
    Error("expected ']'.");
    goto exit;
  }
  ConsumeRSquare();
  
  if (Tok.kind != Token::Colon) {
    Error("expected ':'.");
    goto exit;
  }
  ConsumeExpectedToken(Token::Colon);

  DomainType = ParseTypeSpecifier();
  if (Tok.kind != Token::Arrow) {
    Error("expected '->'.");
    goto exit;
  }
  ConsumeExpectedToken(Token::Arrow);

  RangeType = ParseTypeSpecifier();
  if (Tok.kind != Token::Equals) {
    Error("expected '='.");
    goto exit;
  }
  ConsumeExpectedToken(Token::Equals);

  if (Tok.kind == Token::KWSymbolic) {
    ConsumeExpectedToken(Token::KWSymbolic);    
  } else if (Tok.kind == Token::LSquare) {
    ConsumeLSquare();
    while (Tok.kind != Token::RSquare) {
      if (Tok.kind == Token::EndOfFile) {
        Error("unexpected end of file.");
        goto exit;
      }

      ExprResult Res = ParseNumber(RangeType.get());
      if (Res.isValid())
        Values.push_back(cast<ConstantExpr>(Res.get()));
    }
    ConsumeRSquare();
  } else {
    Error("expected 'symbolic' or '['.");
    goto exit;
  }

  // Type check size.
  if (!Size.isValid()) {
    if (Values.empty()) {
      Error("unsized arrays are not yet supported.");
      Size = 1;
    } else {
      Size = Values.size();
    }
  }

  if (!Values.empty()) {
    if (Size.get() != Values.size()) {
      // FIXME: Lame message.
      Error("constant arrays must be completely specified.");
      Values.clear();
    }

    // for (unsigned i = 0; i != Size.get(); ++i) {
    // TODO: Check: Must be constant expression.
    //}
  }
//.........这里部分代码省略.........
开发者ID:Himeshi,项目名称:klee,代码行数:101,代码来源:Parser.cpp

示例10: TryAnnotateTypeOrScopeToken

/// TryAnnotateTypeOrScopeToken - If the current token position is on a
/// typename (possibly qualified in C++) or a C++ scope specifier not followed
/// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
/// with a single annotation token representing the typename or C++ scope
/// respectively.
/// This simplifies handling of C++ scope specifiers and allows efficient
/// backtracking without the need to re-parse and resolve nested-names and
/// typenames.
/// It will mainly be called when we expect to treat identifiers as typenames
/// (if they are typenames). For example, in C we do not expect identifiers
/// inside expressions to be treated as typenames so it will not be called
/// for expressions in C.
/// The benefit for C/ObjC is that a typename will be annotated and
/// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
/// will not be called twice, once to check whether we have a declaration
/// specifier, and another one to get the actual type inside
/// ParseDeclarationSpecifiers).
///
/// This returns true if the token was annotated or an unrecoverable error
/// occurs.
/// 
/// Note that this routine emits an error if you call it with ::new or ::delete
/// as the current tokens, so only call it in contexts where these are invalid.
bool Parser::TryAnnotateTypeOrScopeToken() {
  assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) 
          || Tok.is(tok::kw_typename)) &&
         "Cannot be a type or scope token!");
  
  if (Tok.is(tok::kw_typename)) {
    // Parse a C++ typename-specifier, e.g., "typename T::type".
    //
    //   typename-specifier:
    //     'typename' '::' [opt] nested-name-specifier identifier
    //     'typename' '::' [opt] nested-name-specifier template [opt] 
    //            simple-template-id
    SourceLocation TypenameLoc = ConsumeToken();
    CXXScopeSpec SS;
    bool HadNestedNameSpecifier = ParseOptionalCXXScopeSpecifier(SS);
    if (!HadNestedNameSpecifier) {
      Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
      return false;
    }

    TypeResult Ty;
    if (Tok.is(tok::identifier)) {
      // FIXME: check whether the next token is '<', first!
      Ty = Actions.ActOnTypenameType(TypenameLoc, SS, *Tok.getIdentifierInfo(), 
                                     Tok.getLocation());
    } else if (Tok.is(tok::annot_template_id)) {
      TemplateIdAnnotation *TemplateId 
        = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
      if (TemplateId->Kind == TNK_Function_template) {
        Diag(Tok, diag::err_typename_refers_to_non_type_template)
          << Tok.getAnnotationRange();
        return false;
      }

      AnnotateTemplateIdTokenAsType(0);
      assert(Tok.is(tok::annot_typename) && 
             "AnnotateTemplateIdTokenAsType isn't working properly");
      if (Tok.getAnnotationValue())
        Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(),
                                       Tok.getAnnotationValue());
      else
        Ty = true;
    } else {
      Diag(Tok, diag::err_expected_type_name_after_typename)
        << SS.getRange();
      return false;
    }

    Tok.setKind(tok::annot_typename);
    Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get());
    Tok.setAnnotationEndLoc(Tok.getLocation());
    Tok.setLocation(TypenameLoc);
    PP.AnnotateCachedTokens(Tok);
    return true;
  }

  CXXScopeSpec SS;
  if (getLang().CPlusPlus)
    ParseOptionalCXXScopeSpecifier(SS);

  if (Tok.is(tok::identifier)) {
    // Determine whether the identifier is a type name.
    if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(), 
                                         Tok.getLocation(), CurScope, &SS)) {
      // This is a typename. Replace the current token in-place with an
      // annotation type token.
      Tok.setKind(tok::annot_typename);
      Tok.setAnnotationValue(Ty);
      Tok.setAnnotationEndLoc(Tok.getLocation());
      if (SS.isNotEmpty()) // it was a C++ qualified type name.
        Tok.setLocation(SS.getBeginLoc());
      
      // In case the tokens were cached, have Preprocessor replace
      // them with the annotation token.
      PP.AnnotateCachedTokens(Tok);
      return true;
    } 
//.........这里部分代码省略.........
开发者ID:Killfrra,项目名称:llvm-kernel,代码行数:101,代码来源:Parser.cpp


注:本文中的TypeResult::get方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。