本文整理汇总了C++中ExprResult::isUsable方法的典型用法代码示例。如果您正苦于以下问题:C++ ExprResult::isUsable方法的具体用法?C++ ExprResult::isUsable怎么用?C++ ExprResult::isUsable使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ExprResult
的用法示例。
在下文中一共展示了ExprResult::isUsable方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: LookupInlineAsmIdentifier
ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
UnqualifiedId &Id,
llvm::InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) {
Info.clear();
if (IsUnevaluatedContext)
PushExpressionEvaluationContext(UnevaluatedAbstract,
ReuseLambdaContextDecl);
ExprResult Result = ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Id,
/*trailing lparen*/ false,
/*is & operand*/ false,
/*CorrectionCandidateCallback=*/nullptr,
/*IsInlineAsmIdentifier=*/ true);
if (IsUnevaluatedContext)
PopExpressionEvaluationContext();
if (!Result.isUsable()) return Result;
Result = CheckPlaceholderExpr(Result.get());
if (!Result.isUsable()) return Result;
QualType T = Result.get()->getType();
// For now, reject dependent types.
if (T->isDependentType()) {
Diag(Id.getLocStart(), diag::err_asm_incomplete_type) << T;
return ExprError();
}
// Any sort of function type is fine.
if (T->isFunctionType()) {
return Result;
}
// Otherwise, it needs to be a complete type.
if (RequireCompleteExprType(Result.get(), diag::err_asm_incomplete_type)) {
return ExprError();
}
// Compute the type size (and array length if applicable?).
Info.Type = Info.Size = Context.getTypeSizeInChars(T).getQuantity();
if (T->isArrayType()) {
const ArrayType *ATy = Context.getAsArrayType(T);
Info.Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity();
Info.Length = Info.Size / Info.Type;
}
// We can work with the expression as long as it's not an r-value.
if (!Result.get()->isRValue())
Info.IsVarDecl = true;
return Result;
}
示例2: T
/// \brief Parsing of OpenMP clause 'private', 'firstprivate',
/// 'shared', 'copyin', or 'reduction'.
///
/// private-clause:
/// 'private' '(' list ')'
/// firstprivate-clause:
/// 'firstprivate' '(' list ')'
/// shared-clause:
/// 'shared' '(' list ')'
/// linear-clause:
/// 'linear' '(' list [ ':' linear-step ] ')'
///
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
SourceLocation Loc = Tok.getLocation();
SourceLocation LOpen = ConsumeToken();
SourceLocation ColonLoc = SourceLocation();
// Parse '('.
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
if (T.expectAndConsume(diag::err_expected_lparen_after,
getOpenMPClauseName(Kind)))
return 0;
SmallVector<Expr *, 5> Vars;
bool IsComma = true;
const bool MayHaveTail = (Kind == OMPC_linear);
while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
Tok.isNot(tok::annot_pragma_openmp_end))) {
ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
// Parse variable
ExprResult VarExpr = ParseAssignmentExpression();
if (VarExpr.isUsable()) {
Vars.push_back(VarExpr.take());
} else {
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}
// Skip ',' if any
IsComma = Tok.is(tok::comma);
if (IsComma)
ConsumeToken();
else if (Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end) &&
(!MayHaveTail || Tok.isNot(tok::colon)))
Diag(Tok, diag::err_omp_expected_punc) << getOpenMPClauseName(Kind);
}
// Parse ':' linear-step
Expr *TailExpr = 0;
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
if (MustHaveTail) {
ColonLoc = Tok.getLocation();
ConsumeToken();
ExprResult Tail = ParseAssignmentExpression();
if (Tail.isUsable())
TailExpr = Tail.take();
else
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}
// Parse ')'.
T.consumeClose();
if (Vars.empty() || (MustHaveTail && !TailExpr))
return 0;
return Actions.ActOnOpenMPVarListClause(Kind, Vars, TailExpr, Loc, LOpen,
ColonLoc, Tok.getLocation());
}
示例3: LookupInlineAsmIdentifier
ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
UnqualifiedId &Id,
llvm::InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) {
Info.clear();
if (IsUnevaluatedContext)
PushExpressionEvaluationContext(UnevaluatedAbstract,
ReuseLambdaContextDecl);
ExprResult Result = ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Id,
/*trailing lparen*/ false,
/*is & operand*/ false,
/*CorrectionCandidateCallback=*/nullptr,
/*IsInlineAsmIdentifier=*/ true);
if (IsUnevaluatedContext)
PopExpressionEvaluationContext();
if (!Result.isUsable()) return Result;
Result = CheckPlaceholderExpr(Result.get());
if (!Result.isUsable()) return Result;
// Referring to parameters is not allowed in naked functions.
if (CheckNakedParmReference(Result.get(), *this))
return ExprError();
QualType T = Result.get()->getType();
// For now, reject dependent types.
if (T->isDependentType()) {
Diag(Id.getLocStart(), diag::err_asm_incomplete_type) << T;
return ExprError();
}
// Any sort of function type is fine.
if (T->isFunctionType()) {
return Result;
}
// Otherwise, it needs to be a complete type.
if (RequireCompleteExprType(Result.get(), diag::err_asm_incomplete_type)) {
return ExprError();
}
fillInlineAsmTypeInfo(Context, T, Info);
// We can work with the expression as long as it's not an r-value.
if (!Result.get()->isRValue())
Info.IsVarDecl = true;
return Result;
}
示例4: ActOnDATAConstantExpr
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;
}
示例5: ParsePARAMETERStmt
/// ParsePARAMETERStmt - Parse the PARAMETER statement.
///
/// [R548]:
/// parameter-stmt :=
/// PARAMETER ( named-constant-def-list )
Parser::StmtResult Parser::ParsePARAMETERStmt() {
// Check if this is an assignment.
if (IsNextToken(tok::equal))
return StmtResult();
auto Loc = ConsumeToken();
SmallVector<Stmt*, 8> StmtList;
if(!ExpectAndConsume(tok::l_paren)) {
if(!SkipUntil(tok::l_paren))
return StmtError();
}
while(true) {
auto IDLoc = Tok.getLocation();
auto II = Tok.getIdentifierInfo();
if(!ExpectAndConsume(tok::identifier)) {
if(!SkipUntil(tok::comma)) break;
else continue;
}
auto EqualLoc = Tok.getLocation();
if(!ExpectAndConsume(tok::equal)) {
if(!SkipUntil(tok::comma)) break;
else continue;
}
ExprResult ConstExpr = ParseExpression();
if(ConstExpr.isUsable()) {
auto Stmt = Actions.ActOnPARAMETER(Context, Loc, EqualLoc,
IDLoc, II,
ConstExpr, nullptr);
if(Stmt.isUsable())
StmtList.push_back(Stmt.take());
}
if(ConsumeIfPresent(tok::comma))
continue;
if(isTokenIdentifier() && !Tok.isAtStartOfStatement()) {
ExpectAndConsume(tok::comma);
continue;
}
break;
}
if(!ExpectAndConsume(tok::r_paren))
SkipUntilNextStatement();
return Actions.ActOnCompoundStmt(Context, Loc, StmtList, StmtLabel);
}
示例6: ParseSelectCaseStmt
Parser::StmtResult Parser::ParseSelectCaseStmt() {
auto Loc = ConsumeToken();
ExprResult Operand;
if(ExpectAndConsume(tok::l_paren)) {
Operand = ParseExpectedFollowupExpression("(");
if(Operand.isUsable()) {
if(!ExpectAndConsume(tok::r_paren))
SkipUntilNextStatement();
} else SkipUntilNextStatement();
} else SkipUntilNextStatement();
return Actions.ActOnSelectCaseStmt(Context, Loc, Operand, StmtConstructName, StmtLabel);
}
示例7: CreateArrayElementExprInitializer
void DataStmtEngine::CreateArrayElementExprInitializer(ArrayElementExpr *E,
Expr *Parent) {
auto Target = dyn_cast<VarExpr>(E->getTarget());
if(!Target)
return VisitExpr(E);
if(CheckVar(Target))
return;
auto VD = Target->getVarDecl();
auto ATy = VD->getType()->asArrayType();
auto ElementType = ATy->getElementType();
uint64_t ArraySize;
if(!ATy->EvaluateSize(ArraySize, Context))
return VisitExpr(E);
SmallVector<Expr*, 32> Items(ArraySize);
if(VD->hasInit()) {
assert(isa<ArrayConstructorExpr>(VD->getInit()));
auto InsertPoint = cast<ArrayConstructorExpr>(VD->getInit())->getItems();
for(uint64_t I = 0; I < ArraySize; ++I)
Items[I] = InsertPoint[I];
} else {
for(uint64_t I = 0; I < ArraySize; ++I)
Items[I] = nullptr;
}
uint64_t Offset;
if(!E->EvaluateOffset(Context, Offset, &ImpliedDoEvaluator))
return VisitExpr(E);
ExprResult Val;
if(Parent) {
if(auto SE = dyn_cast<SubstringExpr>(Parent)) {
Val = CreateSubstringExprInitializer(SE, ElementType);
} else if(auto ME = dyn_cast<MemberExpr>(Parent)) {
if(Offset < Items.size()) {
const TypeConstructorExpr *Init = Items[Offset]? cast<TypeConstructorExpr>(Items[Offset]) : nullptr;
Val = CreateMemberExprInitializer(ME, Init);
}
} else llvm_unreachable("invalid expression");
} else Val = getAndCheckAnyValue(ElementType, E);
if(Val.isUsable() && Offset < Items.size()) {
Items[Offset] = Val.get();
VD->setInit(ArrayConstructorExpr::Create(Context, Val.get()->getLocation(),
Items, VD->getType()));
}
}
示例8: ParseCharacterStarLengthSpec
bool Parser::ParseCharacterStarLengthSpec(DeclSpec &DS) {
ExprResult Len;
if(ConsumeIfPresent(tok::l_paren)) {
if(ConsumeIfPresent(tok::star)) {
DS.setStartLengthSelector();
} else Len = ParseExpectedFollowupExpression("(");
if(!ExpectAndConsume(tok::r_paren))
return true;
}
else Len = ParseExpectedFollowupExpression("*");
if(Len.isInvalid()) return true;
if(Len.isUsable()) DS.setLengthSelector(Len.take());
return false;
}
示例9: R
static Expr *buildBuiltinCall(Sema &S, SourceLocation Loc, Builtin::ID Id,
MultiExprArg CallArgs) {
StringRef Name = S.Context.BuiltinInfo.getName(Id);
LookupResult R(S, &S.Context.Idents.get(Name), Loc, Sema::LookupOrdinaryName);
S.LookupName(R, S.TUScope, /*AllowBuiltinCreation=*/true);
auto *BuiltInDecl = R.getAsSingle<FunctionDecl>();
assert(BuiltInDecl && "failed to find builtin declaration");
ExprResult DeclRef =
S.BuildDeclRefExpr(BuiltInDecl, BuiltInDecl->getType(), VK_LValue, Loc);
assert(DeclRef.isUsable() && "Builtin reference cannot fail");
ExprResult Call =
S.ActOnCallExpr(/*Scope=*/nullptr, DeclRef.get(), Loc, CallArgs, Loc);
assert(!Call.isInvalid() && "Call to builtin cannot fail!");
return Call.get();
}
示例10: LookupInlineAsmIdentifier
void ClangAsmParserCallback::LookupInlineAsmIdentifier(
StringRef &LineBuf, llvm::InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) {
// Collect the desired tokens.
SmallVector<Token, 16> LineToks;
const Token *FirstOrigToken = nullptr;
findTokensForString(LineBuf, LineToks, FirstOrigToken);
unsigned NumConsumedToks;
ExprResult Result = TheParser.ParseMSAsmIdentifier(LineToks, NumConsumedToks,
IsUnevaluatedContext);
// If we consumed the entire line, tell MC that.
// Also do this if we consumed nothing as a way of reporting failure.
if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) {
// By not modifying LineBuf, we're implicitly consuming it all.
// Otherwise, consume up to the original tokens.
} else {
assert(FirstOrigToken && "not using original tokens?");
// Since we're using original tokens, apply that offset.
assert(FirstOrigToken[NumConsumedToks].getLocation() ==
LineToks[NumConsumedToks].getLocation());
unsigned FirstIndex = FirstOrigToken - AsmToks.begin();
unsigned LastIndex = FirstIndex + NumConsumedToks - 1;
// The total length we've consumed is the relative offset
// of the last token we consumed plus its length.
unsigned TotalOffset =
(AsmTokOffsets[LastIndex] + AsmToks[LastIndex].getLength() -
AsmTokOffsets[FirstIndex]);
LineBuf = LineBuf.substr(0, TotalOffset);
}
// Initialize Info with the lookup result.
if (!Result.isUsable())
return;
TheParser.getActions().FillInlineAsmIdentifierInfo(Result.get(), Info);
}
示例11: T
/// \brief Parsing of OpenMP clause 'private', 'firstprivate',
/// 'shared', 'copyin', or 'reduction'.
///
/// private-clause:
/// 'private' '(' list ')'
/// firstprivate-clause:
/// 'firstprivate' '(' list ')'
/// shared-clause:
/// 'shared' '(' list ')'
///
OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
SourceLocation Loc = Tok.getLocation();
SourceLocation LOpen = ConsumeToken();
// Parse '('.
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
if (T.expectAndConsume(diag::err_expected_lparen_after,
getOpenMPClauseName(Kind)))
return 0;
SmallVector<Expr *, 5> Vars;
bool IsComma = true;
while (IsComma || (Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end))) {
// Parse variable
ExprResult VarExpr = ParseAssignmentExpression();
if (VarExpr.isUsable()) {
Vars.push_back(VarExpr.take());
} else {
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}
// Skip ',' if any
IsComma = Tok.is(tok::comma);
if (IsComma) {
ConsumeToken();
} else if (Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end)) {
Diag(Tok, diag::err_omp_expected_punc)
<< getOpenMPClauseName(Kind);
}
}
// Parse ')'.
T.consumeClose();
if (Vars.empty())
return 0;
return Actions.ActOnOpenMPVarListClause(Kind, Vars, Loc, LOpen,
Tok.getLocation());
}
示例12: ParseBraceInitializer
/// ParseBraceInitializer - Called when parsing an initializer that has a
/// leading open brace.
///
/// initializer: [C99 6.7.8]
/// '{' initializer-list '}'
/// '{' initializer-list ',' '}'
/// [GNU] '{' '}'
///
/// initializer-list:
/// designation[opt] initializer ...[opt]
/// initializer-list ',' designation[opt] initializer ...[opt]
///
ExprResult Parser::ParseBraceInitializer() {
InMessageExpressionRAIIObject InMessage(*this, false);
BalancedDelimiterTracker T(*this, tok::l_brace);
T.consumeOpen();
SourceLocation LBraceLoc = T.getOpenLocation();
/// InitExprs - This is the actual list of expressions contained in the
/// initializer.
ExprVector InitExprs;
if (Tok.is(tok::r_brace)) {
// Empty initializers are a C++ feature and a GNU extension to C.
if (!getLangOpts().CPlusPlus)
Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
// Match the '}'.
return Actions.ActOnInitList(LBraceLoc, None, ConsumeBrace());
}
// Enter an appropriate expression evaluation context for an initializer list.
EnterExpressionEvaluationContext EnterContext(
Actions, EnterExpressionEvaluationContext::InitList);
bool InitExprsOk = true;
while (1) {
// Handle Microsoft __if_exists/if_not_exists if necessary.
if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
Tok.is(tok::kw___if_not_exists))) {
if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
if (Tok.isNot(tok::comma)) break;
ConsumeToken();
}
if (Tok.is(tok::r_brace)) break;
continue;
}
// Parse: designation[opt] initializer
// If we know that this cannot be a designation, just parse the nested
// initializer directly.
ExprResult SubElt;
if (MayBeDesignationStart())
SubElt = ParseInitializerWithPotentialDesignator();
else
SubElt = ParseInitializer();
if (Tok.is(tok::ellipsis))
SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
SubElt = Actions.CorrectDelayedTyposInExpr(SubElt.get());
// If we couldn't parse the subelement, bail out.
if (SubElt.isUsable()) {
InitExprs.push_back(SubElt.get());
} else {
InitExprsOk = false;
// We have two ways to try to recover from this error: if the code looks
// grammatically ok (i.e. we have a comma coming up) try to continue
// parsing the rest of the initializer. This allows us to emit
// diagnostics for later elements that we find. If we don't see a comma,
// assume there is a parse error, and just skip to recover.
// FIXME: This comment doesn't sound right. If there is a r_brace
// immediately, it can't be an error, since there is no other way of
// leaving this loop except through this if.
if (Tok.isNot(tok::comma)) {
SkipUntil(tok::r_brace, StopBeforeMatch);
break;
}
}
// If we don't have a comma continued list, we're done.
if (Tok.isNot(tok::comma)) break;
// TODO: save comma locations if some client cares.
ConsumeToken();
// Handle trailing comma.
if (Tok.is(tok::r_brace)) break;
}
bool closed = !T.consumeClose();
if (InitExprsOk && closed)
return Actions.ActOnInitList(LBraceLoc, InitExprs,
T.getCloseLocation());
//.........这里部分代码省略.........
示例13: ParseLexedMethodDeclaration
//.........这里部分代码省略.........
Diag(Tok.getLocation(), diag::err_default_arg_unparsed)
<< SourceRange(Tok.getLocation(),
(*Toks)[Toks->size() - 3].getLocation());
}
Actions.ActOnParamDefaultArgument(Param, EqualLoc,
DefArgResult.get());
}
// There could be leftover tokens (e.g. because of an error).
// Skip through until we reach the 'end of default argument' token.
while (Tok.isNot(tok::eof))
ConsumeAnyToken();
if (Tok.is(tok::eof) && Tok.getEofData() == Param)
ConsumeAnyToken();
delete Toks;
LM.DefaultArgs[I].Toks = nullptr;
}
}
// Parse a delayed exception-specification, if there is one.
if (CachedTokens *Toks = LM.ExceptionSpecTokens) {
// Add the 'stop' token.
Token LastExceptionSpecToken = Toks->back();
Token ExceptionSpecEnd;
ExceptionSpecEnd.startToken();
ExceptionSpecEnd.setKind(tok::eof);
ExceptionSpecEnd.setLocation(
LastExceptionSpecToken.getLocation().getLocWithOffset(
LastExceptionSpecToken.getLength()));
ExceptionSpecEnd.setEofData(LM.Method);
Toks->push_back(ExceptionSpecEnd);
// Parse the default argument from its saved token stream.
Toks->push_back(Tok); // So that the current token doesn't get lost
PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
// Consume the previously-pushed token.
ConsumeAnyToken();
// C++11 [expr.prim.general]p3:
// If a declaration declares a member function or member function
// template of a class X, the expression this is a prvalue of type
// "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
// and the end of the function-definition, member-declarator, or
// declarator.
CXXMethodDecl *Method;
if (FunctionTemplateDecl *FunTmpl
= dyn_cast<FunctionTemplateDecl>(LM.Method))
Method = cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
else
Method = cast<CXXMethodDecl>(LM.Method);
Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(),
Method->getTypeQualifiers(),
getLangOpts().CPlusPlus11);
// Parse the exception-specification.
SourceRange SpecificationRange;
SmallVector<ParsedType, 4> DynamicExceptions;
SmallVector<SourceRange, 4> DynamicExceptionRanges;
ExprResult NoexceptExpr;
CachedTokens *ExceptionSpecTokens;
ExceptionSpecificationType EST
= tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange,
DynamicExceptions,
DynamicExceptionRanges, NoexceptExpr,
ExceptionSpecTokens);
if (Tok.isNot(tok::eof) || Tok.getEofData() != LM.Method)
Diag(Tok.getLocation(), diag::err_except_spec_unparsed);
// Attach the exception-specification to the method.
Actions.actOnDelayedExceptionSpecification(LM.Method, EST,
SpecificationRange,
DynamicExceptions,
DynamicExceptionRanges,
NoexceptExpr.isUsable()?
NoexceptExpr.get() : nullptr);
// There could be leftover tokens (e.g. because of an error).
// Skip through until we reach the original token position.
while (Tok.isNot(tok::eof))
ConsumeAnyToken();
// Clean up the remaining EOF token.
if (Tok.is(tok::eof) && Tok.getEofData() == LM.Method)
ConsumeAnyToken();
delete Toks;
LM.ExceptionSpecTokens = nullptr;
}
PrototypeScope.Exit();
// Finish the delayed C++ method declaration.
Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
}
示例14: T
//.........这里部分代码省略.........
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}
if (Tok.is(tok::colon)) {
ColonLoc = ConsumeToken();
} else {
Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
}
} else if (Kind == OMPC_depend) {
// Handle dependency type for depend clause.
ColonProtectionRAIIObject ColonRAII(*this);
DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
DepLinLoc = Tok.getLocation();
if (DepKind == OMPC_DEPEND_unknown) {
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
} else {
ConsumeToken();
}
if (Tok.is(tok::colon)) {
ColonLoc = ConsumeToken();
} else {
Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type";
}
} else if (Kind == OMPC_linear) {
// Try to parse modifier if any.
if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
LinearModifier = static_cast<OpenMPLinearClauseKind>(
getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
DepLinLoc = ConsumeToken();
LinearT.consumeOpen();
NeedRParenForLinear = true;
}
}
SmallVector<Expr *, 5> Vars;
bool IsComma = ((Kind != OMPC_reduction) && (Kind != OMPC_depend)) ||
((Kind == OMPC_reduction) && !InvalidReductionId) ||
((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
Tok.isNot(tok::annot_pragma_openmp_end))) {
ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
// Parse variable
ExprResult VarExpr =
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
if (VarExpr.isUsable()) {
Vars.push_back(VarExpr.get());
} else {
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}
// Skip ',' if any
IsComma = Tok.is(tok::comma);
if (IsComma)
ConsumeToken();
else if (Tok.isNot(tok::r_paren) &&
Tok.isNot(tok::annot_pragma_openmp_end) &&
(!MayHaveTail || Tok.isNot(tok::colon)))
Diag(Tok, diag::err_omp_expected_punc)
<< ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
: getOpenMPClauseName(Kind))
<< (Kind == OMPC_flush);
}
// Parse ')' for linear clause with modifier.
if (NeedRParenForLinear)
LinearT.consumeClose();
// Parse ':' linear-step (or ':' alignment).
Expr *TailExpr = nullptr;
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
if (MustHaveTail) {
ColonLoc = Tok.getLocation();
ConsumeToken();
ExprResult Tail =
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
if (Tail.isUsable())
TailExpr = Tail.get();
else
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
}
// Parse ')'.
T.consumeClose();
if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
(Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
InvalidReductionId)
return nullptr;
return Actions.ActOnOpenMPVarListClause(
Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
ReductionIdScopeSpec,
ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
: DeclarationNameInfo(),
DepKind, LinearModifier, DepLinLoc);
}
示例15: ParseDeclarationTypeSpec
//.........这里部分代码省略.........
if (!AllowSelectors)
break;
if (ConsumeIfPresent(tok::l_paren)) {
Kind = ParseSelector(true);
if (Kind.isInvalid())
return true;
if(!ExpectAndConsume(tok::r_paren, 0, "", tok::r_paren))
return true;
}
break;
case DeclSpec::TST_character:
// [R424]:
// char-selector :=
// length-selector
// or ( LEN = type-param-value , KIND = scalar-int-initialization-expr )
// or ( type-param-value , #
// # [ KIND = ] scalar-int-initialization-expr )
// or ( KIND = scalar-int-initialization-expr [, LEN = type-param-value])
//
// [R425]:
// length-selector :=
// ( [ LEN = ] type-param-value )
// or * char-length [,]
//
// [R426]:
// char-length :=
// ( type-param-value )
// or scalar-int-literal-constant
//
// [R402]:
// type-param-value :=
// scalar-int-expr
// or *
// or :
ConsumeToken();
if(ConsumeIfPresent(tok::star)) {
ParseCharacterStarLengthSpec(DS);
if(AllowOptionalCommaAfterCharLength)
ConsumeIfPresent(tok::comma);
} else {
if (!AllowSelectors)
break;
if(ConsumeIfPresent(tok::l_paren)) {
if(IsPresent(tok::kw_LEN)) {
Len = ParseSelector(false);
if (Len.isInvalid())
return true;
} else if(IsPresent(tok::kw_KIND)) {
Kind = ParseSelector(true);
if (Kind.isInvalid())
return true;
} else {
Len = ParseExpectedFollowupExpression("(");
if(Len.isInvalid())
return true;
}
if(ConsumeIfPresent(tok::comma)) {
// FIXME:
if (Tok.is(tok::kw_LEN)) {
if (Len.isInvalid())
return Diag.ReportError(Tok.getLocation(),
"multiple LEN selectors for this type");
Len = ParseSelector(false);
if (Len.isInvalid())
return true;
} else if (Tok.is(tok::kw_KIND)) {
if (Kind.isInvalid())
return Diag.ReportError(Tok.getLocation(),
"multiple KIND selectors for this type");
Kind = ParseSelector(true);
if (Kind.isInvalid())
return true;
} else {
if (Kind.isInvalid())
return Diag.ReportError(Tok.getLocation(),
"multiple KIND selectors for this type");
ExprResult KindExpr = ParseExpression();
Kind = KindExpr;
}
}
if(!ExpectAndConsume(tok::r_paren))
return true;
}
}
break;
}
// Set the selectors for declspec.
if(Kind.isUsable()) DS.setKindSelector(Kind.get());
if(Len.isUsable()) DS.setLengthSelector(Len.get());
return false;
}