diff options
Diffstat (limited to 'clang/include/clang/Parse/Parser.h')
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 358 |
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 |