summaryrefslogtreecommitdiff
path: root/clang/include/clang/Parse/Parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Parse/Parser.h')
-rw-r--r--clang/include/clang/Parse/Parser.h358
1 files changed, 291 insertions, 67 deletions
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index e320c96478188..e809d87b59a0f 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -13,7 +13,6 @@
#ifndef LLVM_CLANG_PARSE_PARSER_H
#define LLVM_CLANG_PARSE_PARSER_H
-#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Availability.h"
#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/OpenMPKinds.h"
@@ -24,6 +23,7 @@
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Frontend/OpenMP/OMPContext.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -49,6 +49,10 @@ namespace clang {
class OMPClause;
class ObjCTypeParamList;
class ObjCTypeParameter;
+ struct OMPTraitProperty;
+ struct OMPTraitSelector;
+ struct OMPTraitSet;
+ class OMPTraitInfo;
/// Parser - This implements a parser for the C family of languages. After
/// parsing units of the grammar, productions are invoked to handle whatever has
@@ -178,6 +182,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> PCSectionHandler;
std::unique_ptr<PragmaHandler> MSCommentHandler;
std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
+ std::unique_ptr<PragmaHandler> FloatControlHandler;
std::unique_ptr<PragmaHandler> MSPointersToMembers;
std::unique_ptr<PragmaHandler> MSVtorDisp;
std::unique_ptr<PragmaHandler> MSInitSeg;
@@ -201,6 +206,8 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> STDCCXLIMITHandler;
std::unique_ptr<PragmaHandler> STDCUnknownHandler;
std::unique_ptr<PragmaHandler> AttributePragmaHandler;
+ std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
+ std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
std::unique_ptr<CommentHandler> CommentSemaHandler;
@@ -234,6 +241,9 @@ class Parser : public CodeCompletionHandler {
/// The "depth" of the template parameters currently being parsed.
unsigned TemplateParameterDepth;
+ /// Current kind of OpenMP clause
+ OpenMPClauseKind OMPClauseKind = llvm::omp::OMPC_unknown;
+
/// RAII class that manages the template parameter depth.
class TemplateParameterDepthRAII {
unsigned &Depth;
@@ -270,6 +280,22 @@ class Parser : public CodeCompletionHandler {
/// top-level declaration is finished.
SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
+ void MaybeDestroyTemplateIds() {
+ if (!TemplateIds.empty() &&
+ (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens()))
+ DestroyTemplateIds();
+ }
+ void DestroyTemplateIds();
+
+ /// RAII object to destroy TemplateIdAnnotations where possible, from a
+ /// likely-good position during parsing.
+ struct DestroyTemplateIdAnnotationsRAIIObj {
+ Parser &Self;
+
+ DestroyTemplateIdAnnotationsRAIIObj(Parser &Self) : Self(Self) {}
+ ~DestroyTemplateIdAnnotationsRAIIObj() { Self.MaybeDestroyTemplateIds(); }
+ };
+
/// Identifiers which have been declared within a tentative parse.
SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
@@ -719,6 +745,10 @@ private:
/// #pragma STDC FENV_ACCESS...
void HandlePragmaFEnvAccess();
+ /// Handle the annotation token produced for
+ /// #pragma float_control
+ void HandlePragmaFloatControl();
+
/// \brief Handle the annotation token produced for
/// #pragma clang fp ...
void HandlePragmaFP();
@@ -761,13 +791,17 @@ public:
}
/// getTypeAnnotation - Read a parsed type out of an annotation token.
- static ParsedType getTypeAnnotation(const Token &Tok) {
+ static TypeResult getTypeAnnotation(const Token &Tok) {
+ if (!Tok.getAnnotationValue())
+ return TypeError();
return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue());
}
private:
- static void setTypeAnnotation(Token &Tok, ParsedType T) {
- Tok.setAnnotationValue(T.getAsOpaquePtr());
+ static void setTypeAnnotation(Token &Tok, TypeResult T) {
+ assert((T.isInvalid() || T.get()) &&
+ "produced a valid-but-null type annotation?");
+ Tok.setAnnotationValue(T.isInvalid() ? nullptr : T.get().getAsOpaquePtr());
}
static NamedDecl *getNonTypeAnnotation(const Token &Tok) {
@@ -806,6 +840,16 @@ public:
bool IsNewScope);
bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+ bool MightBeCXXScopeToken() {
+ return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+ (Tok.is(tok::annot_template_id) &&
+ NextToken().is(tok::coloncolon)) ||
+ Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
+ }
+ bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
+ return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
+ }
+
private:
enum AnnotatedNameKind {
/// Annotation has failed and emitted an error.
@@ -1047,12 +1091,40 @@ public:
}
};
+ /// Introduces zero or more scopes for parsing. The scopes will all be exited
+ /// when the object is destroyed.
+ class MultiParseScope {
+ Parser &Self;
+ unsigned NumScopes = 0;
+
+ MultiParseScope(const MultiParseScope&) = delete;
+
+ public:
+ MultiParseScope(Parser &Self) : Self(Self) {}
+ void Enter(unsigned ScopeFlags) {
+ Self.EnterScope(ScopeFlags);
+ ++NumScopes;
+ }
+ void Exit() {
+ while (NumScopes) {
+ Self.ExitScope();
+ --NumScopes;
+ }
+ }
+ ~MultiParseScope() {
+ Exit();
+ }
+ };
+
/// EnterScope - Start a new scope.
void EnterScope(unsigned ScopeFlags);
/// ExitScope - Pop a scope off the scope stack.
void ExitScope();
+ /// Re-enter the template scopes for a declaration that might be a template.
+ unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D);
+
private:
/// RAII object used to modify the scope flags for the current scope.
class ParseScopeFlags {
@@ -1101,7 +1173,8 @@ public:
/// it (unless StopBeforeMatch is specified). Because we cannot guarantee
/// that the token will ever occur, this skips to the next token, or to some
/// likely good stopping point. If Flags has StopAtSemi flag, skipping will
- /// stop at a ';' character.
+ /// stop at a ';' character. Balances (), [], and {} delimiter tokens while
+ /// skipping.
///
/// If SkipUntil finds the specified token, it returns true, otherwise it
/// returns false.
@@ -1236,13 +1309,7 @@ private:
Decl *D;
CachedTokens Toks;
- /// Whether this member function had an associated template
- /// scope. When true, D is a template declaration.
- /// otherwise, it is a member function declaration.
- bool TemplateScope;
-
- explicit LexedMethod(Parser* P, Decl *MD)
- : Self(P), D(MD), TemplateScope(false) {}
+ explicit LexedMethod(Parser *P, Decl *MD) : Self(P), D(MD) {}
void ParseLexedMethodDefs() override;
};
@@ -1272,8 +1339,7 @@ private:
/// argument (C++ [class.mem]p2).
struct LateParsedMethodDeclaration : public LateParsedDeclaration {
explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
- : Self(P), Method(M), TemplateScope(false),
- ExceptionSpecTokens(nullptr) {}
+ : Self(P), Method(M), ExceptionSpecTokens(nullptr) {}
void ParseLexedMethodDeclarations() override;
@@ -1282,11 +1348,6 @@ private:
/// Method - The method declaration.
Decl *Method;
- /// Whether this member function had an associated template
- /// scope. When true, D is a template declaration.
- /// otherwise, it is a member function declaration.
- bool TemplateScope;
-
/// DefaultArgs - Contains the parameters of the function and
/// their default arguments. At least one of the parameters will
/// have a default argument, but all of the parameters of the
@@ -1331,18 +1392,13 @@ private:
/// parsed after the corresponding top-level class is complete.
struct ParsingClass {
ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface)
- : TopLevelClass(TopLevelClass), TemplateScope(false),
- IsInterface(IsInterface), TagOrTemplate(TagOrTemplate) { }
+ : TopLevelClass(TopLevelClass), IsInterface(IsInterface),
+ TagOrTemplate(TagOrTemplate) {}
/// Whether this is a "top-level" class, meaning that it is
/// not nested within another class.
bool TopLevelClass : 1;
- /// Whether this class had an associated template
- /// scope. When true, TagOrTemplate is a template declaration;
- /// otherwise, it is a tag declaration.
- bool TemplateScope : 1;
-
/// Whether this class is an __interface.
bool IsInterface : 1;
@@ -1441,11 +1497,14 @@ private:
SourceRange getSourceRange() const LLVM_READONLY;
};
+ // In ParseCXXInlineMethods.cpp.
+ struct ReenterTemplateScopeRAII;
+ struct ReenterClassScopeRAII;
+
void LexTemplateFunctionForLateParsing(CachedTokens &Toks);
void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT);
static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT);
- static void LateTemplateParserCleanupCallback(void *P);
Sema::ParsingClassState
PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
@@ -1689,6 +1748,8 @@ public:
unsigned &NumLineToksConsumed,
bool IsUnevaluated);
+ ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
+
private:
ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
@@ -1739,6 +1800,7 @@ private:
ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
ExprResult ParseUnaryExprOrTypeTraitExpression();
ExprResult ParseBuiltinPrimaryExpression();
+ ExprResult ParseUniqueStableNameExpression();
ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
bool &isCastExpr,
@@ -1781,8 +1843,6 @@ private:
SourceLocation LParenLoc,
SourceLocation RParenLoc);
- ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
-
ExprResult ParseGenericSelectionExpression();
ExprResult ParseObjCBoolLiteral();
@@ -1801,7 +1861,9 @@ private:
bool EnteringContext, IdentifierInfo &II,
CXXScopeSpec &SS);
- bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, ParsedType ObjectType,
+ bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
+ ParsedType ObjectType,
+ bool ObjectHasErrors,
bool EnteringContext,
bool *MayBePseudoDestructor = nullptr,
bool IsTypename = false,
@@ -1923,6 +1985,7 @@ private:
//===--------------------------------------------------------------------===//
// C++ Concepts
+ ExprResult ParseRequiresExpression();
void ParseTrailingRequiresClause(Declarator &D);
//===--------------------------------------------------------------------===//
@@ -1939,7 +2002,8 @@ private:
}
bool MayBeDesignationStart();
ExprResult ParseBraceInitializer();
- ExprResult ParseInitializerWithPotentialDesignator();
+ ExprResult ParseInitializerWithPotentialDesignator(
+ llvm::function_ref<void(const Designation &)> CodeCompleteCB);
//===--------------------------------------------------------------------===//
// clang Expressions
@@ -2007,8 +2071,9 @@ private:
StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
bool ParseParenExprOrCondition(StmtResult *InitStmt,
Sema::ConditionResult &CondResult,
- SourceLocation Loc,
- Sema::ConditionKind CK);
+ SourceLocation Loc, Sema::ConditionKind CK,
+ SourceLocation *LParenLoc = nullptr,
+ SourceLocation *RParenLoc = nullptr);
StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
@@ -2135,6 +2200,68 @@ private:
llvm_unreachable("Missing DeclSpecContext case");
}
+ /// Whether a defining-type-specifier is permitted in a given context.
+ enum class AllowDefiningTypeSpec {
+ /// The grammar doesn't allow a defining-type-specifier here, and we must
+ /// not parse one (eg, because a '{' could mean something else).
+ No,
+ /// The grammar doesn't allow a defining-type-specifier here, but we permit
+ /// one for error recovery purposes. Sema will reject.
+ NoButErrorRecovery,
+ /// The grammar allows a defining-type-specifier here, even though it's
+ /// always invalid. Sema will reject.
+ YesButInvalid,
+ /// The grammar allows a defining-type-specifier here, and one can be valid.
+ Yes
+ };
+
+ /// Is this a context in which we are parsing defining-type-specifiers (and
+ /// so permit class and enum definitions in addition to non-defining class and
+ /// enum elaborated-type-specifiers)?
+ static AllowDefiningTypeSpec
+ isDefiningTypeSpecifierContext(DeclSpecContext DSC) {
+ switch (DSC) {
+ case DeclSpecContext::DSC_normal:
+ case DeclSpecContext::DSC_class:
+ case DeclSpecContext::DSC_top_level:
+ case DeclSpecContext::DSC_alias_declaration:
+ case DeclSpecContext::DSC_objc_method_result:
+ return AllowDefiningTypeSpec::Yes;
+
+ case DeclSpecContext::DSC_condition:
+ case DeclSpecContext::DSC_template_param:
+ return AllowDefiningTypeSpec::YesButInvalid;
+
+ case DeclSpecContext::DSC_template_type_arg:
+ case DeclSpecContext::DSC_type_specifier:
+ return AllowDefiningTypeSpec::NoButErrorRecovery;
+
+ case DeclSpecContext::DSC_trailing:
+ return AllowDefiningTypeSpec::No;
+ }
+ llvm_unreachable("Missing DeclSpecContext case");
+ }
+
+ /// Is this a context in which an opaque-enum-declaration can appear?
+ static bool isOpaqueEnumDeclarationContext(DeclSpecContext DSC) {
+ switch (DSC) {
+ case DeclSpecContext::DSC_normal:
+ case DeclSpecContext::DSC_class:
+ case DeclSpecContext::DSC_top_level:
+ return true;
+
+ case DeclSpecContext::DSC_alias_declaration:
+ case DeclSpecContext::DSC_objc_method_result:
+ case DeclSpecContext::DSC_condition:
+ case DeclSpecContext::DSC_template_param:
+ case DeclSpecContext::DSC_template_type_arg:
+ case DeclSpecContext::DSC_type_specifier:
+ case DeclSpecContext::DSC_trailing:
+ return false;
+ }
+ llvm_unreachable("Missing DeclSpecContext case");
+ }
+
/// Is this a context in which we can perform class template argument
/// deduction?
static bool isClassTemplateDeductionContext(DeclSpecContext DSC) {
@@ -2225,7 +2352,7 @@ private:
AccessSpecifier AS, DeclSpecContext DSC);
void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
- Decl *TagDecl);
+ RecordDecl *TagDecl);
void ParseStructDeclaration(
ParsingDeclSpec &DS,
@@ -2362,17 +2489,14 @@ private:
True, False, Ambiguous, Error
};
- /// Based only on the given token kind, determine whether we know that
- /// we're at the start of an expression or a type-specifier-seq (which may
- /// be an expression, in C++).
+ /// Determine whether we could have an enum-base.
///
- /// This routine does not attempt to resolve any of the trick cases, e.g.,
- /// those involving lookup of identifiers.
+ /// \p AllowSemi If \c true, then allow a ';' after the enum-base; otherwise
+ /// only consider this to be an enum-base if the next token is a '{'.
///
- /// \returns \c TPR_true if this token starts an expression, \c TPR_false if
- /// this token starts a type-specifier-seq, or \c TPR_ambiguous if it cannot
- /// tell.
- TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind);
+ /// \return \c false if this cannot possibly be an enum base; \c true
+ /// otherwise.
+ bool isEnumBase(bool AllowSemi);
/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
/// declaration specifier, TPResult::False if it is not,
@@ -2395,6 +2519,11 @@ private:
/// rather than a less-than expression.
TPResult isTemplateArgumentList(unsigned TokensToSkip);
+ /// Determine whether an '(' after an 'explicit' keyword is part of a C++20
+ /// 'explicit(bool)' declaration, in earlier language modes where that is an
+ /// extension.
+ TPResult isExplicitBool();
+
/// Determine whether an identifier has been tentatively declared as a
/// non-type. Such tentative declarations should not be found to name a type
/// during a tentative parse, but also should not be annotated as a non-type.
@@ -2422,6 +2551,10 @@ private:
TPResult TryParseBracketDeclarator();
TPResult TryConsumeDeclarationSpecifier();
+ /// Try to skip a possibly empty sequence of 'attribute-specifier's without
+ /// full validation of the syntactic structure of attributes.
+ bool TrySkipAttributes();
+
public:
TypeResult ParseTypeName(SourceRange *Range = nullptr,
DeclaratorContext Context
@@ -2548,13 +2681,15 @@ private:
D.takeAttributes(attrs, endLoc);
}
}
- void MaybeParseCXX11Attributes(ParsedAttributes &attrs,
+ bool MaybeParseCXX11Attributes(ParsedAttributes &attrs,
SourceLocation *endLoc = nullptr) {
if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
ParsedAttributesWithRange attrsWithRange(AttrFactory);
ParseCXX11Attributes(attrsWithRange, endLoc);
attrs.takeAllFrom(attrsWithRange);
+ return true;
}
+ return false;
}
void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
SourceLocation *endLoc = nullptr,
@@ -2671,6 +2806,7 @@ private:
SourceLocation &EllipsisLoc);
void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
SourceLocation *endLoc = nullptr);
+ ExprResult ParseExtIntegerArgument();
VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
@@ -2756,7 +2892,7 @@ private:
Declarator &D,
SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
void ParseParameterDeclarationClause(
- Declarator &D,
+ DeclaratorContext DeclaratorContext,
ParsedAttributes &attrs,
SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
SourceLocation &EllipsisLoc);
@@ -2884,11 +3020,12 @@ private:
AccessSpecifier getAccessSpecifierIfPresent() const;
bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
+ ParsedType ObjectType,
+ bool ObjectHadErrors,
SourceLocation TemplateKWLoc,
IdentifierInfo *Name,
SourceLocation NameLoc,
bool EnteringContext,
- ParsedType ObjectType,
UnqualifiedId &Id,
bool AssumeTemplateId);
bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
@@ -2901,20 +3038,69 @@ private:
DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr,
CachedTokens &Toks,
SourceLocation Loc);
- /// Parses OpenMP context selectors and calls \p Callback for each
- /// successfully parsed context selector.
- bool
- parseOpenMPContextSelectors(SourceLocation Loc,
- SmallVectorImpl<Sema::OMPCtxSelectorData> &Data);
+
+ /// Parse a property kind into \p TIProperty for the selector set \p Set and
+ /// selector \p Selector.
+ void parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
+ llvm::omp::TraitSet Set,
+ llvm::omp::TraitSelector Selector,
+ llvm::StringMap<SourceLocation> &Seen);
+
+ /// Parse a selector kind into \p TISelector for the selector set \p Set.
+ void parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
+ llvm::omp::TraitSet Set,
+ llvm::StringMap<SourceLocation> &Seen);
+
+ /// Parse a selector set kind into \p TISet.
+ void parseOMPTraitSetKind(OMPTraitSet &TISet,
+ llvm::StringMap<SourceLocation> &Seen);
+
+ /// Parses an OpenMP context property.
+ void parseOMPContextProperty(OMPTraitSelector &TISelector,
+ llvm::omp::TraitSet Set,
+ llvm::StringMap<SourceLocation> &Seen);
+
+ /// Parses an OpenMP context selector.
+ void parseOMPContextSelector(OMPTraitSelector &TISelector,
+ llvm::omp::TraitSet Set,
+ llvm::StringMap<SourceLocation> &SeenSelectors);
+
+ /// Parses an OpenMP context selector set.
+ void parseOMPContextSelectorSet(OMPTraitSet &TISet,
+ llvm::StringMap<SourceLocation> &SeenSets);
+
+ /// Parses OpenMP context selectors.
+ bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI);
+
+ /// Parse a `match` clause for an '#pragma omp declare variant'. Return true
+ /// if there was an error.
+ bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI);
/// Parse clauses for '#pragma omp declare variant'.
void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
SourceLocation Loc);
+
/// Parse clauses for '#pragma omp declare target'.
DeclGroupPtrTy ParseOMPDeclareTargetClauses();
/// Parse '#pragma omp end declare target'.
void ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
SourceLocation Loc);
+
+ /// Skip tokens until a `annot_pragma_openmp_end` was found. Emit a warning if
+ /// it is not the current token.
+ void skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind);
+
+ /// Check the \p FoundKind against the \p ExpectedKind, if not issue an error
+ /// that the "end" matching the "begin" directive of kind \p BeginKind was not
+ /// found. Finally, if the expected kind was found or if \p SkipUntilOpenMPEnd
+ /// is set, skip ahead using the helper `skipUntilPragmaOpenMPEnd`.
+ void parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
+ OpenMPDirectiveKind ExpectedKind,
+ OpenMPDirectiveKind FoundKind,
+ SourceLocation MatchingLoc,
+ SourceLocation FoundLoc,
+ bool SkipUntilOpenMPEnd);
+
/// Parses declarative OpenMP directives.
DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
@@ -2933,6 +3119,10 @@ private:
DeclarationName &Name,
AccessSpecifier AS = AS_none);
+ /// Tries to parse cast part of OpenMP array shaping operation:
+ /// '[' expression ']' { '[' expression ']' } ')'.
+ bool tryParseOpenMPArrayShapingCastPart();
+
/// Parses simple list of variables.
///
/// \param Kind Kind of the directive.
@@ -2977,11 +3167,13 @@ private:
/// Parses clause with a single expression and an additional argument
/// of a kind \a Kind.
///
+ /// \param DKind Directive kind.
/// \param Kind Kind of current clause.
/// \param ParseOnly true to skip the clause's semantic actions and return
/// nullptr.
///
- OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
+ OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
+ OpenMPClauseKind Kind,
bool ParseOnly);
/// Parses clause without any additional arguments.
///
@@ -2999,6 +3191,16 @@ private:
OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind Kind, bool ParseOnly);
+ /// Parses and creates OpenMP 5.0 iterators expression:
+ /// <iterators> = 'iterator' '(' { [ <iterator-type> ] identifier =
+ /// <range-specification> }+ ')'
+ ExprResult ParseOpenMPIteratorsExpr();
+
+ /// Parses allocators and traits in the context of the uses_allocator clause.
+ /// Expected format:
+ /// '(' { <allocator> [ '(' <allocator_traits> ')' ] }+ ')'
+ OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind);
+
public:
/// Parses simple expression in parens for single-expression clauses of OpenMP
/// constructs.
@@ -3008,32 +3210,31 @@ public:
/// Data used for parsing list of variables in OpenMP clauses.
struct OpenMPVarListDataTy {
- Expr *TailExpr = nullptr;
+ Expr *DepModOrTailExpr = nullptr;
SourceLocation ColonLoc;
SourceLocation RLoc;
CXXScopeSpec ReductionOrMapperIdScopeSpec;
DeclarationNameInfo ReductionOrMapperId;
int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or
///< lastprivate clause.
- SmallVector<OpenMPMapModifierKind, OMPMapClause::NumberOfModifiers>
+ SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
MapTypeModifiers;
- SmallVector<SourceLocation, OMPMapClause::NumberOfModifiers>
+ SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
MapTypeModifiersLoc;
bool IsMapTypeImplicit = false;
- SourceLocation DepLinMapLastLoc;
+ SourceLocation ExtraModifierLoc;
};
/// Parses clauses with list.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind,
SmallVectorImpl<Expr *> &Vars,
OpenMPVarListDataTy &Data);
- bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
- bool AllowDestructorName,
- bool AllowConstructorName,
+ bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
+ bool ObjectHadErrors, bool EnteringContext,
+ bool AllowDestructorName, bool AllowConstructorName,
bool AllowDeductionGuide,
- ParsedType ObjectType,
- SourceLocation *TemplateKWLoc,
- UnqualifiedId &Result);
+ SourceLocation *TemplateKWLoc, UnqualifiedId &Result);
+
/// Parses the mapper modifier in map, to, and from clauses.
bool parseMapperModifier(OpenMPVarListDataTy &Data);
/// Parses map-type-modifiers in map clause.
@@ -3058,19 +3259,19 @@ private:
DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none);
- bool ParseTemplateParameters(unsigned Depth,
+ bool ParseTemplateParameters(MultiParseScope &TemplateScopes, unsigned Depth,
SmallVectorImpl<NamedDecl *> &TemplateParams,
SourceLocation &LAngleLoc,
SourceLocation &RAngleLoc);
bool ParseTemplateParameterList(unsigned Depth,
SmallVectorImpl<NamedDecl*> &TemplateParams);
- bool isStartOfTemplateTypeParameter(bool &ScopeError);
+ TPResult isStartOfTemplateTypeParameter();
NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position);
NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position);
NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
bool isTypeConstraintAnnotation();
- bool TryAnnotateTypeConstraint(CXXScopeSpec &SS);
+ bool TryAnnotateTypeConstraint();
NamedDecl *
ParseConstrainedTemplateTypeParameter(unsigned Depth, unsigned Position);
void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
@@ -3082,7 +3283,8 @@ private:
// C++ 14.3: Template arguments [temp.arg]
typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
- bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
+ bool ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,
+ SourceLocation &RAngleLoc,
bool ConsumeLastToken,
bool ObjCGenericList);
bool ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
@@ -3096,7 +3298,8 @@ private:
UnqualifiedId &TemplateName,
bool AllowTypeAnnotation = true,
bool TypeConstraint = false);
- void AnnotateTemplateIdTokenAsType(bool IsClassName = false);
+ void AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
+ bool IsClassName = false);
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
ParsedTemplateArgument ParseTemplateTemplateArgument();
ParsedTemplateArgument ParseTemplateArgument();
@@ -3148,6 +3351,27 @@ private:
unsigned ArgumentIndex) override;
void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) override;
void CodeCompleteNaturalLanguage() override;
+
+ class GNUAsmQualifiers {
+ unsigned Qualifiers = AQ_unspecified;
+
+ public:
+ enum AQ {
+ AQ_unspecified = 0,
+ AQ_volatile = 1,
+ AQ_inline = 2,
+ AQ_goto = 4,
+ };
+ static const char *getQualifierName(AQ Qualifier);
+ bool setAsmQualifier(AQ Qualifier);
+ inline bool isVolatile() const { return Qualifiers & AQ_volatile; };
+ inline bool isInline() const { return Qualifiers & AQ_inline; };
+ inline bool isGoto() const { return Qualifiers & AQ_goto; }
+ };
+ bool isGCCAsmStatement(const Token &TokAfterAsm) const;
+ bool isGNUAsmQualifier(const Token &TokAfterAsm) const;
+ GNUAsmQualifiers::AQ getGNUAsmQualifier(const Token &Tok) const;
+ bool parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ);
};
} // end namespace clang