本文整理汇总了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();
}
示例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);
}
示例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();
}
示例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:
//.........这里部分代码省略.........
示例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();
//.........这里部分代码省略.........
示例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) {
//.........这里部分代码省略.........
示例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)
//.........这里部分代码省略.........
示例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;
}
示例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.
//}
}
//.........这里部分代码省略.........
示例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;
}
//.........这里部分代码省略.........