diff options
Diffstat (limited to 'include/clang/Parse/Parser.h')
-rw-r--r-- | include/clang/Parse/Parser.h | 185 |
1 files changed, 135 insertions, 50 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 1029a90..bd49988 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -45,6 +45,7 @@ namespace clang { class InMessageExpressionRAIIObject; class PoisonSEHIdentifiersRAIIObject; class VersionTuple; + class OMPClause; /// Parser - This implements a parser for the C family of languages. After /// parsing units of the grammar, productions are invoked to handle whatever has @@ -101,15 +102,17 @@ class Parser : public CodeCompletionHandler { /// Contextual keywords for Microsoft extensions. IdentifierInfo *Ident__except; + mutable IdentifierInfo *Ident_sealed; /// Ident_super - IdentifierInfo for "super", to support fast /// comparison. IdentifierInfo *Ident_super; - /// Ident_vector and Ident_pixel - cached IdentifierInfo's for - /// "vector" and "pixel" fast comparison. Only present if - /// AltiVec enabled. + /// Ident_vector, Ident_pixel, Ident_bool - cached IdentifierInfo's + /// for "vector", "pixel", and "bool" fast comparison. Only present + /// if AltiVec enabled. IdentifierInfo *Ident_vector; IdentifierInfo *Ident_pixel; + IdentifierInfo *Ident_bool; /// Objective-C contextual keywords. mutable IdentifierInfo *Ident_instancetype; @@ -150,6 +153,7 @@ class Parser : public CodeCompletionHandler { OwningPtr<CommentHandler> CommentSemaHandler; OwningPtr<PragmaHandler> OpenMPHandler; OwningPtr<PragmaHandler> MSCommentHandler; + OwningPtr<PragmaHandler> MSDetectMismatchHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ @@ -398,7 +402,8 @@ private: /// \brief Abruptly cut off parsing; mainly used when we have reached the /// code-completion point. void cutOffParsing() { - PP.setCodeCompletionReached(); + if (PP.isCodeCompletionEnabled()) + PP.setCodeCompletionReached(); // Cut off parsing by acting as if we reached the end-of-file. Tok.setKind(tok::eof); } @@ -419,6 +424,10 @@ private: void HandlePragmaMSStruct(); /// \brief Handle the annotation token produced for + /// #pragma comment... + void HandlePragmaMSComment(); + + /// \brief Handle the annotation token produced for /// #pragma align... void HandlePragmaAlign(); @@ -525,7 +534,8 @@ private: bool &isInvalid) { if (!getLangOpts().AltiVec || (Tok.getIdentifierInfo() != Ident_vector && - Tok.getIdentifierInfo() != Ident_pixel)) + Tok.getIdentifierInfo() != Ident_pixel && + Tok.getIdentifierInfo() != Ident_bool)) return false; return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid); @@ -545,6 +555,13 @@ private: const char *&PrevSpec, unsigned &DiagID, bool &isInvalid); + /// TryKeywordIdentFallback - For compatibility with system headers using + /// keywords as identifiers, attempt to convert the current token to an + /// identifier and optionally disable the keyword for the remainder of the + /// translation unit. This returns false if the token was not replaced, + /// otherwise emits a diagnostic and returns true. + bool TryKeywordIdentFallback(bool DisableKeyword); + /// \brief Get the TemplateIdAnnotation from the token. TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok); @@ -599,6 +616,7 @@ private: assert(!isActive && "Forgot to call Commit or Revert!"); } }; + class UnannotatedTentativeParsingAction; /// ObjCDeclContextSwitch - An object used to switch context from /// an objective-c decl context to its enclosing decl context and @@ -725,32 +743,45 @@ private: void CheckNestedObjCContexts(SourceLocation AtLoc); public: + + /// \brief Control flags for SkipUntil functions. + enum SkipUntilFlags { + StopAtSemi = 1 << 0, ///< Stop skipping at semicolon + /// \brief Stop skipping at specified token, but don't skip the token itself + StopBeforeMatch = 1 << 1, + StopAtCodeCompletion = 1 << 2 ///< Stop at code completion + }; + + friend LLVM_CONSTEXPR SkipUntilFlags operator|(SkipUntilFlags L, + SkipUntilFlags R) { + return static_cast<SkipUntilFlags>(static_cast<unsigned>(L) | + static_cast<unsigned>(R)); + } + /// SkipUntil - Read tokens until we get to the specified token, then consume - /// it (unless DontConsume is true). Because we cannot guarantee that the - /// token will ever occur, this skips to the next token, or to some likely - /// good stopping point. If StopAtSemi is true, skipping will stop at a ';' - /// character. + /// 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. /// /// If SkipUntil finds the specified token, it returns true, otherwise it /// returns false. - bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true, - bool DontConsume = false, bool StopAtCodeCompletion = false) { - return SkipUntil(llvm::makeArrayRef(T), StopAtSemi, DontConsume, - StopAtCodeCompletion); + bool SkipUntil(tok::TokenKind T, + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) { + return SkipUntil(llvm::makeArrayRef(T), Flags); } - bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true, - bool DontConsume = false, bool StopAtCodeCompletion = false) { + bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) { tok::TokenKind TokArray[] = {T1, T2}; - return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); + return SkipUntil(TokArray, Flags); } bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3, - bool StopAtSemi = true, bool DontConsume = false, - bool StopAtCodeCompletion = false) { + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) { tok::TokenKind TokArray[] = {T1, T2, T3}; - return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); + return SkipUntil(TokArray, Flags); } - bool SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi = true, - bool DontConsume = false, bool StopAtCodeCompletion = false); + bool SkipUntil(ArrayRef<tok::TokenKind> Toks, + SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)); /// SkipMalformedDecl - Read tokens until we get to some likely good stopping /// point for skipping past a simple-declaration. @@ -1042,32 +1073,21 @@ private: SourceRange getSourceRange() const LLVM_READONLY; }; - /// \brief Contains a late templated function. - /// Will be parsed at the end of the translation unit. - struct LateParsedTemplatedFunction { - explicit LateParsedTemplatedFunction(Decl *MD) - : D(MD) {} - - CachedTokens Toks; - - /// \brief The template function declaration to be late parsed. - Decl *D; - }; - void LexTemplateFunctionForLateParsing(CachedTokens &Toks); - void ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT); - typedef llvm::DenseMap<const FunctionDecl*, LateParsedTemplatedFunction*> - LateParsedTemplateMapT; - LateParsedTemplateMapT LateParsedTemplateMap; + void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT); - static void LateTemplateParserCallback(void *P, const FunctionDecl *FD); - void LateTemplateParser(const FunctionDecl *FD); + static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT); Sema::ParsingClassState PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface); void DeallocateParsedClasses(ParsingClass *Class); void PopParsingClass(Sema::ParsingClassState); + enum CachedInitKind { + CIK_DefaultArgument, + CIK_DefaultInitializer + }; + NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS, AttributeList *AccessAttrs, ParsingDeclarator &D, @@ -1089,6 +1109,8 @@ private: void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI); void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod); bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks); + bool ConsumeAndStoreInitializer(CachedTokens &Toks, CachedInitKind CIK); + bool ConsumeAndStoreConditional(CachedTokens &Toks); bool ConsumeAndStoreUntil(tok::TokenKind T1, CachedTokens &Toks, bool StopAtSemi = true, @@ -1274,6 +1296,12 @@ private: ArrayRef<Expr *> Args) = 0, Expr *Data = 0); + /// ParseSimpleExpressionList - A simple comma-separated list of expressions, + /// used for misc language extensions. + bool ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs, + SmallVectorImpl<SourceLocation> &CommaLocs); + + /// ParenParseOption - Control what ParseParenExpression will parse. enum ParenParseOption { SimpleExpr, // Only parse '(' expression ')' @@ -1325,7 +1353,8 @@ private: // [...] () -> type {...} ExprResult ParseLambdaExpression(); ExprResult TryParseLambdaExpression(); - Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro); + Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro, + bool *SkippedInits = 0); bool TryParseLambdaIntroducer(LambdaIntroducer &Intro); ExprResult ParseLambdaExpressionAfterIntroducer( LambdaIntroducer &Intro); @@ -1461,10 +1490,7 @@ private: /// A SmallVector of types. typedef SmallVector<ParsedType, 12> TypeVector; - StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0) { - StmtVector Stmts; - return ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); - } + StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0); StmtResult ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement, SourceLocation *TrailingElseLoc = 0); @@ -1628,6 +1654,9 @@ private: AccessSpecifier AS = AS_none, DeclSpecContext DSC = DSC_normal, LateParsedAttrList *LateAttrs = 0); + bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, + DeclSpecContext DSContext, + LateParsedAttrList *LateAttrs = 0); void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none, DeclSpecContext DSC = DSC_normal); @@ -1800,6 +1829,11 @@ private: isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(), bool *HasMissingTypename = 0); + /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or + /// \c TPResult::Ambiguous, determine whether the decl-specifier would be + /// a type-specifier other than a cv-qualifier. + bool isCXXDeclarationSpecifierAType(); + /// \brief 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. @@ -1812,15 +1846,18 @@ private: // that more tentative parsing is necessary for disambiguation. // They all consume tokens, so backtracking should be used after calling them. - TPResult TryParseDeclarationSpecifier(bool *HasMissingTypename = 0); TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl); TPResult TryParseTypeofSpecifier(); TPResult TryParseProtocolQualifiers(); + TPResult TryParsePtrOperatorSeq(); + TPResult TryParseOperatorId(); TPResult TryParseInitDeclaratorList(); TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true); - TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = 0); + TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = 0, + bool VersusTemplateArg = false); TPResult TryParseFunctionDeclarator(); TPResult TryParseBracketDeclarator(); + TPResult TryConsumeDeclarationSpecifier(); public: TypeResult ParseTypeName(SourceRange *Range = 0, @@ -1866,6 +1903,10 @@ private: // for example, attributes appertain to decl specifiers. void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs); + /// \brief Diagnose and skip C++11 attributes that appear in syntactic + /// locations where attributes are not allowed. + void DiagnoseAndSkipCXX11Attributes(); + void MaybeParseGNUAttributes(Declarator &D, LateParsedAttrList *LateAttrs = 0) { if (Tok.is(tok::kw___attribute)) { @@ -1891,6 +1932,7 @@ private: IdentifierInfo *ScopeName, SourceLocation ScopeLoc, AttributeList::Syntax Syntax); + IdentifierLoc *ParseIdentifierLoc(); void MaybeParseCXX11Attributes(Declarator &D) { if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { @@ -1961,6 +2003,11 @@ private: ParsedAttributes &Attrs, SourceLocation *EndLoc); + void ParseAttributeWithTypeArg(IdentifierInfo &AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, + SourceLocation *EndLoc); + void ParseTypeofSpecifier(DeclSpec &DS); SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS, @@ -2024,7 +2071,8 @@ private: void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true, bool CXX11AttributesAllowed = true, - bool AtomicAllowed = true); + bool AtomicAllowed = true, + bool IdentifierRequired = false); void ParseDirectDeclarator(Declarator &D); void ParseParenDeclarator(Declarator &D); void ParseFunctionDeclarator(Declarator &D, @@ -2035,11 +2083,11 @@ private: bool isFunctionDeclaratorIdentifierList(); void ParseFunctionDeclaratorIdentifierList( Declarator &D, - SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo); + SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo); void ParseParameterDeclarationClause( Declarator &D, ParsedAttributes &attrs, - SmallVector<DeclaratorChunk::ParamInfo, 16> &ParamInfo, + SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo, SourceLocation &EllipsisLoc); void ParseBracketDeclarator(Declarator &D); @@ -2060,6 +2108,8 @@ private: isCXX11AttributeSpecifier(bool Disambiguate = false, bool OuterMightBeMessageSend = false); + void DiagnoseUnexpectedNamespace(NamedDecl *Context); + Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd, SourceLocation InlineLoc = SourceLocation()); void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, @@ -2134,9 +2184,44 @@ private: //===--------------------------------------------------------------------===// // OpenMP: Directives and clauses. + /// \brief Parses declarative OpenMP directives. DeclGroupPtrTy ParseOpenMPDeclarativeDirective(); + /// \brief Parses simple list of variables. + /// + /// \param Kind Kind of the directive. + /// \param [out] VarList List of referenced variables. + /// \param AllowScopeSpecifier true, if the variables can have fully + /// qualified names. + /// bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, - SmallVectorImpl<DeclarationNameInfo> &IdList); + SmallVectorImpl<Expr *> &VarList, + bool AllowScopeSpecifier); + /// \brief Parses declarative or executable directive. + StmtResult ParseOpenMPDeclarativeOrExecutableDirective(); + /// \brief Parses clause of kind \a CKind for directive of a kind \a Kind. + /// + /// \param DKind Kind of current directive. + /// \param CKind Kind of current clause. + /// \param FirstClause true, if this is the first clause of a kind \a CKind + /// in current directive. + /// + OMPClause *ParseOpenMPClause(OpenMPDirectiveKind DKind, + OpenMPClauseKind CKind, bool FirstClause); + /// \brief Parses clause with a single expression of a kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPSingleExprClause(OpenMPClauseKind Kind); + /// \brief Parses simple clause of a kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind); + /// \brief Parses clause with the list of variables of a kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPVarListClause(OpenMPClauseKind Kind); public: bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, |