diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/Parse/Parser.h')
-rw-r--r-- | contrib/llvm/tools/clang/include/clang/Parse/Parser.h | 532 |
1 files changed, 347 insertions, 185 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h index bd49988c5b00..c58c41a44c58 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h @@ -20,12 +20,13 @@ #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/LoopHint.h" #include "clang/Sema/Sema.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/SaveAndRestore.h" +#include <memory> #include <stack> namespace clang { @@ -40,7 +41,6 @@ namespace clang { class ParsingDeclSpec; class ParsingDeclarator; class ParsingFieldDeclarator; - class PragmaUnusedHandler; class ColonProtectionRAIIObject; class InMessageExpressionRAIIObject; class PoisonSEHIdentifiersRAIIObject; @@ -52,7 +52,6 @@ namespace clang { /// been read. /// class Parser : public CodeCompletionHandler { - friend class PragmaUnusedHandler; friend class ColonProtectionRAIIObject; friend class InMessageExpressionRAIIObject; friend class PoisonSEHIdentifiersRAIIObject; @@ -73,7 +72,7 @@ class Parser : public CodeCompletionHandler { SourceLocation PrevTokLocation; unsigned short ParenCount, BracketCount, BraceCount; - + /// Actions - These are the callbacks we invoke as we parse various constructs /// in the file. Sema &Actions; @@ -136,24 +135,37 @@ class Parser : public CodeCompletionHandler { mutable IdentifierInfo *Ident_final; mutable IdentifierInfo *Ident_override; - // C++ type trait keywords that have can be reverted to identifiers and - // still used as type traits. - llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertableTypeTraits; - - OwningPtr<PragmaHandler> AlignHandler; - OwningPtr<PragmaHandler> GCCVisibilityHandler; - OwningPtr<PragmaHandler> OptionsHandler; - OwningPtr<PragmaHandler> PackHandler; - OwningPtr<PragmaHandler> MSStructHandler; - OwningPtr<PragmaHandler> UnusedHandler; - OwningPtr<PragmaHandler> WeakHandler; - OwningPtr<PragmaHandler> RedefineExtnameHandler; - OwningPtr<PragmaHandler> FPContractHandler; - OwningPtr<PragmaHandler> OpenCLExtensionHandler; - OwningPtr<CommentHandler> CommentSemaHandler; - OwningPtr<PragmaHandler> OpenMPHandler; - OwningPtr<PragmaHandler> MSCommentHandler; - OwningPtr<PragmaHandler> MSDetectMismatchHandler; + // Some token kinds such as C++ type traits can be reverted to identifiers and + // still get used as keywords depending on context. + llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind> + ContextualKeywords; + + std::unique_ptr<PragmaHandler> AlignHandler; + std::unique_ptr<PragmaHandler> GCCVisibilityHandler; + std::unique_ptr<PragmaHandler> OptionsHandler; + std::unique_ptr<PragmaHandler> PackHandler; + std::unique_ptr<PragmaHandler> MSStructHandler; + std::unique_ptr<PragmaHandler> UnusedHandler; + std::unique_ptr<PragmaHandler> WeakHandler; + std::unique_ptr<PragmaHandler> RedefineExtnameHandler; + std::unique_ptr<PragmaHandler> FPContractHandler; + std::unique_ptr<PragmaHandler> OpenCLExtensionHandler; + std::unique_ptr<PragmaHandler> OpenMPHandler; + std::unique_ptr<PragmaHandler> MSCommentHandler; + std::unique_ptr<PragmaHandler> MSDetectMismatchHandler; + std::unique_ptr<PragmaHandler> MSPointersToMembers; + std::unique_ptr<PragmaHandler> MSVtorDisp; + std::unique_ptr<PragmaHandler> MSInitSeg; + std::unique_ptr<PragmaHandler> MSDataSeg; + std::unique_ptr<PragmaHandler> MSBSSSeg; + std::unique_ptr<PragmaHandler> MSConstSeg; + std::unique_ptr<PragmaHandler> MSCodeSeg; + std::unique_ptr<PragmaHandler> MSSection; + std::unique_ptr<PragmaHandler> OptimizeHandler; + std::unique_ptr<PragmaHandler> LoopHintHandler; + std::unique_ptr<PragmaHandler> UnrollHintHandler; + + std::unique_ptr<CommentHandler> CommentSemaHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ @@ -167,7 +179,7 @@ class Parser : public CodeCompletionHandler { /// ColonProtectionRAIIObject RAII object. bool ColonIsSacred; - /// \brief When true, we are directly inside an Objective-C messsage + /// \brief When true, we are directly inside an Objective-C message /// send expression. /// /// This is managed by the \c InMessageExpressionRAIIObject class, and @@ -193,6 +205,10 @@ class Parser : public CodeCompletionHandler { ++Depth; ++AddedLevels; } + void addDepth(unsigned D) { + Depth += D; + AddedLevels += D; + } unsigned getDepth() const { return Depth; } }; @@ -229,6 +245,9 @@ public: const Token &getCurToken() const { return Tok; } Scope *getCurScope() const { return Actions.getCurScope(); } + void incrementMSLocalManglingNumber() const { + return Actions.incrementMSLocalManglingNumber(); + } Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); } @@ -246,7 +265,7 @@ public: typedef clang::TypeResult TypeResult; typedef Expr *ExprArg; - typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg; + typedef MutableArrayRef<Stmt*> MultiStmtArg; typedef Sema::FullExprArg FullExprArg; ExprResult ExprError() { return ExprResult(true); } @@ -266,24 +285,40 @@ public: /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if /// the EOF was encountered. bool ParseTopLevelDecl(DeclGroupPtrTy &Result); + bool ParseTopLevelDecl() { + DeclGroupPtrTy Result; + return ParseTopLevelDecl(Result); + } /// ConsumeToken - Consume the current 'peek token' and lex the next one. - /// This does not work with all kinds of tokens: strings and specific other - /// tokens must be consumed with custom methods below. This returns the - /// location of the consumed token. - SourceLocation ConsumeToken(bool ConsumeCodeCompletionTok = false) { - assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() && - !isTokenBrace() && + /// This does not work with special tokens: string literals, code completion + /// and balanced tokens must be handled using the specific consume methods. + /// Returns the location of the consumed token. + SourceLocation ConsumeToken() { + assert(!isTokenSpecial() && "Should consume special tokens with Consume*Token"); - - if (!ConsumeCodeCompletionTok && Tok.is(tok::code_completion)) - return handleUnexpectedCodeCompletionToken(); - PrevTokLocation = Tok.getLocation(); PP.Lex(Tok); return PrevTokLocation; } + bool TryConsumeToken(tok::TokenKind Expected) { + if (Tok.isNot(Expected)) + return false; + assert(!isTokenSpecial() && + "Should consume special tokens with Consume*Token"); + PrevTokLocation = Tok.getLocation(); + PP.Lex(Tok); + return true; + } + + bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) { + if (!TryConsumeToken(Expected)) + return false; + Loc = PrevTokLocation; + return true; + } + private: //===--------------------------------------------------------------------===// // Low-Level token peeking and consumption methods. @@ -301,12 +336,15 @@ private: bool isTokenBrace() const { return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace; } - /// isTokenStringLiteral - True if this token is a string-literal. - /// bool isTokenStringLiteral() const { return tok::isStringLiteral(Tok.getKind()); } + /// isTokenSpecial - True if this token requires special consumption methods. + bool isTokenSpecial() const { + return isTokenStringLiteral() || isTokenParen() || isTokenBracket() || + isTokenBrace() || Tok.is(tok::code_completion); + } /// \brief Returns true if the current token is '=' or is a type of '='. /// For typos, give a fixit to '=' @@ -318,14 +356,16 @@ private: SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) { if (isTokenParen()) return ConsumeParen(); - else if (isTokenBracket()) + if (isTokenBracket()) return ConsumeBracket(); - else if (isTokenBrace()) + if (isTokenBrace()) return ConsumeBrace(); - else if (isTokenStringLiteral()) + if (isTokenStringLiteral()) return ConsumeStringToken(); - else - return ConsumeToken(ConsumeCodeCompletionTok); + if (Tok.is(tok::code_completion)) + return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken() + : handleUnexpectedCodeCompletionToken(); + return ConsumeToken(); } /// ConsumeParen - This consume method keeps the paren count up-to-date. @@ -383,8 +423,9 @@ private: /// \brief Consume the current code-completion token. /// - /// This routine should be called to consume the code-completion token once - /// a code-completion action has already been invoked. + /// This routine can be called to consume the code-completion token and + /// continue processing in special cases where \c cutOffParsing() isn't + /// desired, such as token caching or completion with lookahead. SourceLocation ConsumeCodeCompletionToken() { assert(Tok.is(tok::code_completion)); PrevTokLocation = Tok.getLocation(); @@ -408,6 +449,20 @@ private: Tok.setKind(tok::eof); } + /// \brief Determine if we're at the end of the file or at a transition + /// between modules. + bool isEofOrEom() { + tok::TokenKind Kind = Tok.getKind(); + return Kind == tok::eof || Kind == tok::annot_module_begin || + Kind == tok::annot_module_end || Kind == tok::annot_module_include; + } + + /// \brief Initialize all pragma handlers. + void initializePragmaHandlers(); + + /// \brief Destroy and reset all pragma handlers. + void resetPragmaHandlers(); + /// \brief Handle the annotation token produced for #pragma unused(...) void HandlePragmaUnused(); @@ -427,6 +482,18 @@ private: /// #pragma comment... void HandlePragmaMSComment(); + void HandlePragmaMSPointersToMembers(); + + void HandlePragmaMSVtorDisp(); + + void HandlePragmaMSPragma(); + bool HandlePragmaMSSection(StringRef PragmaName, + SourceLocation PragmaLocation); + bool HandlePragmaMSSegment(StringRef PragmaName, + SourceLocation PragmaLocation); + bool HandlePragmaMSInitSeg(StringRef PragmaName, + SourceLocation PragmaLocation); + /// \brief Handle the annotation token produced for /// #pragma align... void HandlePragmaAlign(); @@ -455,6 +522,10 @@ private: /// #pragma clang __debug captured StmtResult HandlePragmaCaptured(); + /// \brief Handle the annotation token produced for + /// #pragma clang loop and #pragma unroll. + LoopHint HandlePragmaLoopHint(); + /// GetLookAheadToken - This peeks ahead N tokens and returns that token /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1) /// returns the token after Tok, etc. @@ -521,7 +592,7 @@ private: ANK_Success }; AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC = 0); + CorrectionCandidateCallback *CCC = nullptr); /// Push a tok::annot_cxxscope token onto the token stream. void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation); @@ -562,6 +633,12 @@ private: /// otherwise emits a diagnostic and returns true. bool TryKeywordIdentFallback(bool DisableKeyword); + /// TryIdentKeywordUpgrade - Convert the current identifier token back to + /// its original kind and return true if it was disabled by + /// TryKeywordIdentFallback(), otherwise return false. Use this to + /// contextually enable keywords. + bool TryIdentKeywordUpgrade(); + /// \brief Get the TemplateIdAnnotation from the token. TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok); @@ -628,7 +705,7 @@ private: public: explicit ObjCDeclContextSwitch(Parser &p) : P(p), DC(p.getObjCDeclContext()), - WithinObjCContainer(P.ParsingInObjCContainer, DC != 0) { + WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) { if (DC) P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC)); } @@ -641,12 +718,14 @@ private: /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the /// input. If so, it is consumed and false is returned. /// - /// If the input is malformed, this emits the specified diagnostic. Next, if - /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is + /// If a trivial punctuator misspelling is encountered, a FixIt error + /// diagnostic is issued and false is returned after recovery. + /// + /// If the input is malformed, this emits the specified diagnostic and true is /// returned. - bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag, - const char *DiagMsg = "", - tok::TokenKind SkipToTok = tok::unknown); + bool ExpectAndConsume(tok::TokenKind ExpectedTok, + unsigned Diag = diag::err_expected, + StringRef DiagMsg = ""); /// \brief The parser expects a semicolon and, if present, will consume it. /// @@ -684,14 +763,18 @@ public: public: // ParseScope - Construct a new object to manage a scope in the // parser Self where the new Scope is created with the flags - // ScopeFlags, but only when ManageScope is true (the default). If - // ManageScope is false, this object does nothing. - ParseScope(Parser *Self, unsigned ScopeFlags, bool ManageScope = true) + // ScopeFlags, but only when we aren't about to enter a compound statement. + ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true, + bool BeforeCompoundStmt = false) : Self(Self) { - if (ManageScope) + if (EnteredScope && !BeforeCompoundStmt) Self->EnterScope(ScopeFlags); - else - this->Self = 0; + else { + if (BeforeCompoundStmt) + Self->incrementMSLocalManglingNumber(); + + this->Self = nullptr; + } } // Exit - Exit the scope associated with this object now, rather @@ -699,7 +782,7 @@ public: void Exit() { if (Self) { Self->ExitScope(); - Self = 0; + Self = nullptr; } } @@ -818,10 +901,10 @@ private: LateParsedClass(Parser *P, ParsingClass *C); virtual ~LateParsedClass(); - virtual void ParseLexedMethodDeclarations(); - virtual void ParseLexedMemberInitializers(); - virtual void ParseLexedMethodDefs(); - virtual void ParseLexedAttributes(); + void ParseLexedMethodDeclarations() override; + void ParseLexedMemberInitializers() override; + void ParseLexedMethodDefs() override; + void ParseLexedAttributes() override; private: Parser *Self; @@ -845,7 +928,7 @@ private: SourceLocation Loc) : Self(P), AttrName(Name), AttrNameLoc(Loc) {} - virtual void ParseLexedAttributes(); + void ParseLexedAttributes() override; void addDecl(Decl *D) { Decls.push_back(D); } }; @@ -877,7 +960,7 @@ private: explicit LexedMethod(Parser* P, Decl *MD) : Self(P), D(MD), TemplateScope(false) {} - virtual void ParseLexedMethodDefs(); + void ParseLexedMethodDefs() override; }; /// LateParsedDefaultArgument - Keeps track of a parameter that may @@ -886,7 +969,7 @@ private: /// (C++ [class.mem]p2). struct LateParsedDefaultArgument { explicit LateParsedDefaultArgument(Decl *P, - CachedTokens *Toks = 0) + CachedTokens *Toks = nullptr) : Param(P), Toks(Toks) { } /// Param - The parameter declaration for this parameter. @@ -905,9 +988,10 @@ private: /// argument (C++ [class.mem]p2). struct LateParsedMethodDeclaration : public LateParsedDeclaration { explicit LateParsedMethodDeclaration(Parser *P, Decl *M) - : Self(P), Method(M), TemplateScope(false), ExceptionSpecTokens(0) { } + : Self(P), Method(M), TemplateScope(false), + ExceptionSpecTokens(nullptr) {} - virtual void ParseLexedMethodDeclarations(); + void ParseLexedMethodDeclarations() override; Parser* Self; @@ -938,7 +1022,7 @@ private: LateParsedMemberInitializer(Parser *P, Decl *FD) : Self(P), Field(FD) { } - virtual void ParseLexedMemberInitializers(); + void ParseLexedMemberInitializers() override; Parser *Self; @@ -1028,7 +1112,7 @@ private: /// specifiers. struct ParsedTemplateInfo { ParsedTemplateInfo() - : Kind(NonTemplate), TemplateParams(0), TemplateLoc() { } + : Kind(NonTemplate), TemplateParams(nullptr), TemplateLoc() { } ParsedTemplateInfo(TemplateParameterLists *TemplateParams, bool isSpecialization, @@ -1039,7 +1123,7 @@ private: explicit ParsedTemplateInfo(SourceLocation ExternLoc, SourceLocation TemplateLoc) - : Kind(ExplicitInstantiation), TemplateParams(0), + : Kind(ExplicitInstantiation), TemplateParams(nullptr), ExternLoc(ExternLoc), TemplateLoc(TemplateLoc), LastParameterListWasEmpty(false){ } @@ -1132,12 +1216,12 @@ private: }; DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs, - ParsingDeclSpec *DS = 0); + ParsingDeclSpec *DS = nullptr); bool isDeclarationAfterDeclarator(); bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator); DeclGroupPtrTy ParseDeclarationOrFunctionDefinition( ParsedAttributesWithRange &attrs, - ParsingDeclSpec *DS = 0, + ParsingDeclSpec *DS = nullptr, AccessSpecifier AS = AS_none); DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, ParsingDeclSpec &DS, @@ -1145,11 +1229,11 @@ private: Decl *ParseFunctionDefinition(ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), - LateParsedAttrList *LateParsedAttrs = 0); + LateParsedAttrList *LateParsedAttrs = nullptr); void ParseKNRParamDeclarations(Declarator &D); // EndLoc, if non-NULL, is filled with the location of the last token of // the simple-asm. - ExprResult ParseSimpleAsm(SourceLocation *EndLoc = 0); + ExprResult ParseSimpleAsm(SourceLocation *EndLoc = nullptr); ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations @@ -1289,12 +1373,12 @@ private: typedef SmallVector<SourceLocation, 20> CommaLocsTy; /// ParseExpressionList - Used for C/C++ (argument-)expression-list. - bool ParseExpressionList(SmallVectorImpl<Expr*> &Exprs, - SmallVectorImpl<SourceLocation> &CommaLocs, - void (Sema::*Completer)(Scope *S, - Expr *Data, - ArrayRef<Expr *> Args) = 0, - Expr *Data = 0); + bool + ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, + SmallVectorImpl<SourceLocation> &CommaLocs, + void (Sema::*Completer)(Scope *S, Expr *Data, + ArrayRef<Expr *> Args) = nullptr, + Expr *Data = nullptr); /// ParseSimpleExpressionList - A simple comma-separated list of expressions, /// used for misc language extensions. @@ -1315,9 +1399,9 @@ private: ParsedType &CastTy, SourceLocation &RParenLoc); - ExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, - ParsedType &CastTy, - BalancedDelimiterTracker &Tracker); + ExprResult ParseCXXAmbiguousParenExpression( + ParenParseOption &ExprType, ParsedType &CastTy, + BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt); ExprResult ParseCompoundLiteralExpression(ParsedType Ty, SourceLocation LParenLoc, SourceLocation RParenLoc); @@ -1341,9 +1425,9 @@ private: bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext, - bool *MayBePseudoDestructor = 0, + bool *MayBePseudoDestructor = nullptr, bool IsTypename = false, - IdentifierInfo **LastII = 0); + IdentifierInfo **LastII = nullptr); void CheckForLParenAfterColonColon(); @@ -1354,7 +1438,7 @@ private: ExprResult ParseLambdaExpression(); ExprResult TryParseLambdaExpression(); Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro, - bool *SkippedInits = 0); + bool *SkippedInits = nullptr); bool TryParseLambdaIntroducer(LambdaIntroducer &Intro); ExprResult ParseLambdaExpressionAfterIntroducer( LambdaIntroducer &Intro); @@ -1490,10 +1574,10 @@ private: /// A SmallVector of types. typedef SmallVector<ParsedType, 12> TypeVector; - StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0); - StmtResult ParseStatementOrDeclaration(StmtVector &Stmts, - bool OnlyStatement, - SourceLocation *TrailingElseLoc = 0); + StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr); + StmtResult + ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement, + SourceLocation *TrailingElseLoc = nullptr); StmtResult ParseStatementOrDeclarationAfterAttributes( StmtVector &Stmts, bool OnlyStatement, @@ -1524,6 +1608,9 @@ private: StmtResult ParseReturnStatement(); StmtResult ParseAsmStatement(bool &msAsm); StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc); + StmtResult ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement, + SourceLocation *TrailingElseLoc, + ParsedAttributesWithRange &Attrs); /// \brief Describes the behavior that should be taken for an __if_exists /// block. @@ -1582,6 +1669,7 @@ private: StmtResult ParseSEHTryBlockCommon(SourceLocation Loc); StmtResult ParseSEHExceptBlock(SourceLocation Loc); StmtResult ParseSEHFinallyBlock(SourceLocation Loc); + StmtResult ParseSEHLeaveStatement(); //===--------------------------------------------------------------------===// // Objective-C Statements @@ -1604,9 +1692,29 @@ private: DSC_class, // class context, enables 'friend' DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list DSC_trailing, // C++11 trailing-type-specifier in a trailing return type - DSC_top_level // top-level/namespace declaration context + DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration + DSC_top_level, // top-level/namespace declaration context + DSC_template_type_arg // template type argument context }; + /// Is this a context in which we are parsing just a type-specifier (or + /// trailing-type-specifier)? + static bool isTypeSpecifier(DeclSpecContext DSC) { + switch (DSC) { + case DSC_normal: + case DSC_class: + case DSC_top_level: + return false; + + case DSC_template_type_arg: + case DSC_type_specifier: + case DSC_trailing: + case DSC_alias_declaration: + return true; + } + llvm_unreachable("Missing DeclSpecContext case"); + } + /// Information on a C++0x for-range-initializer found while parsing a /// declaration which turns out to be a for-range-declaration. struct ForRangeInit { @@ -1624,17 +1732,19 @@ private: SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs, bool RequireSemi, - ForRangeInit *FRI = 0); + ForRangeInit *FRI = nullptr); bool MightBeDeclarator(unsigned Context); DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context, bool AllowFunctionDefinitions, - SourceLocation *DeclEnd = 0, - ForRangeInit *FRI = 0); + SourceLocation *DeclEnd = nullptr, + ForRangeInit *FRI = nullptr); Decl *ParseDeclarationAfterDeclarator(Declarator &D, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); bool ParseAsmAttributesAfterDeclarator(Declarator &D); - Decl *ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); + Decl *ParseDeclarationAfterDeclaratorAndAttributes( + Declarator &D, + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), + ForRangeInit *FRI = nullptr); Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope); Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope); @@ -1653,10 +1763,10 @@ private: const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), AccessSpecifier AS = AS_none, DeclSpecContext DSC = DSC_normal, - LateParsedAttrList *LateAttrs = 0); + LateParsedAttrList *LateAttrs = nullptr); bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, - DeclSpecContext DSContext, - LateParsedAttrList *LateAttrs = 0); + DeclSpecContext DSContext, + LateParsedAttrList *LateAttrs = nullptr); void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none, DeclSpecContext DSC = DSC_normal); @@ -1696,7 +1806,7 @@ private: /// cast. Return false if it's no a decl-specifier, or we're not sure. bool isKnownToBeDeclarationSpecifier() { if (getLangOpts().CPlusPlus) - return isCXXDeclarationSpecifier() == TPResult::True(); + return isCXXDeclarationSpecifier() == TPResult::True; return isDeclarationSpecifier(true); } @@ -1719,6 +1829,9 @@ private: return isDeclarationSpecifier(true); } + /// \brief Determine whether this is a C++1z for-range-identifier. + bool isForRangeIdentifier(); + /// \brief Determine whether we are currently at the start of an Objective-C /// class message that appears to be missing the open bracket '['. bool isStartOfObjCClassMessageMissingOpenBracket(); @@ -1726,12 +1839,13 @@ private: /// \brief Starting with a scope specifier, identifier, or /// template-id that refers to the current class, determine whether /// this is a constructor declarator. - bool isConstructorDeclarator(); + bool isConstructorDeclarator(bool Unqualified); /// \brief Specifies the context in which type-id/expression /// disambiguation will occur. enum TentativeCXXTypeIdContext { TypeIdInParens, + TypeIdUnambiguous, TypeIdAsTemplateArgument }; @@ -1750,6 +1864,16 @@ private: return isTypeIdInParens(isAmbiguous); } + /// \brief Checks if the current tokens form type-id or expression. + /// It is similar to isTypeIdInParens but does not suppose that type-id + /// is in parenthesis. + bool isTypeIdUnambiguously() { + bool IsAmbiguous; + if (getLangOpts().CPlusPlus) + return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous); + return isTypeSpecifierQualifier(); + } + /// isCXXDeclarationStatement - C++-specialized function that disambiguates /// between a declaration or an expression statement, when parsing function /// bodies. Returns true for declaration, false for expression. @@ -1769,7 +1893,7 @@ private: /// might be a constructor-style initializer. /// If during the disambiguation process a parsing error is encountered, /// the function returns true to let the declaration parsing code handle it. - bool isCXXFunctionDeclarator(bool *IsAmbiguous = 0); + bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr); /// isCXXConditionDeclaration - Disambiguates between a declaration or an /// expression for a condition of a if/switch/while/for statement. @@ -1785,25 +1909,8 @@ private: /// TPResult - Used as the result value for functions whose purpose is to /// disambiguate C++ constructs by "tentatively parsing" them. - /// This is a class instead of a simple enum because the implicit enum-to-bool - /// conversions may cause subtle bugs. - class TPResult { - enum Result { - TPR_true, - TPR_false, - TPR_ambiguous, - TPR_error - }; - Result Res; - TPResult(Result result) : Res(result) {} - public: - static TPResult True() { return TPR_true; } - static TPResult False() { return TPR_false; } - static TPResult Ambiguous() { return TPR_ambiguous; } - static TPResult Error() { return TPR_error; } - - bool operator==(const TPResult &RHS) const { return Res == RHS.Res; } - bool operator!=(const TPResult &RHS) const { return Res != RHS.Res; } + enum class TPResult { + True, False, Ambiguous, Error }; /// \brief Based only on the given token kind, determine whether we know that @@ -1818,16 +1925,16 @@ private: /// tell. TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind); - /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a - /// declaration specifier, TPResult::False() if it is not, - /// TPResult::Ambiguous() if it could be either a decl-specifier or a - /// function-style cast, and TPResult::Error() if a parsing error was + /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a + /// declaration specifier, TPResult::False if it is not, + /// TPResult::Ambiguous if it could be either a decl-specifier or a + /// function-style cast, and TPResult::Error if a parsing error was /// encountered. If it could be a braced C++11 function-style cast, returns /// BracedCastResult. /// Doesn't consume tokens. TPResult - isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(), - bool *HasMissingTypename = 0); + isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False, + bool *HasMissingTypename = nullptr); /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or /// \c TPResult::Ambiguous, determine whether the decl-specifier would be @@ -1840,9 +1947,9 @@ private: bool isTentativelyDeclared(IdentifierInfo *II); // "Tentative parsing" functions, used for disambiguation. If a parsing error - // is encountered they will return TPResult::Error(). - // Returning TPResult::True()/False() indicates that the ambiguity was - // resolved and tentative parsing may stop. TPResult::Ambiguous() indicates + // is encountered they will return TPResult::Error. + // Returning TPResult::True/False indicates that the ambiguity was + // resolved and tentative parsing may stop. TPResult::Ambiguous indicates // that more tentative parsing is necessary for disambiguation. // They all consume tokens, so backtracking should be used after calling them. @@ -1853,19 +1960,20 @@ private: TPResult TryParseOperatorId(); TPResult TryParseInitDeclaratorList(); TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true); - TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = 0, - bool VersusTemplateArg = false); + TPResult + TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr, + bool VersusTemplateArg = false); TPResult TryParseFunctionDeclarator(); TPResult TryParseBracketDeclarator(); TPResult TryConsumeDeclarationSpecifier(); public: - TypeResult ParseTypeName(SourceRange *Range = 0, + TypeResult ParseTypeName(SourceRange *Range = nullptr, Declarator::TheContext Context = Declarator::TypeNameContext, AccessSpecifier AS = AS_none, - Decl **OwnedType = 0, - ParsedAttributes *Attrs = 0); + Decl **OwnedType = nullptr, + ParsedAttributes *Attrs = nullptr); private: void ParseBlockId(SourceLocation CaretLoc); @@ -1903,35 +2011,51 @@ private: // for example, attributes appertain to decl specifiers. void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs); + /// \brief Skip C++11 attributes and return the end location of the last one. + /// \returns SourceLocation() if there are no attributes. + SourceLocation SkipCXX11Attributes(); + /// \brief Diagnose and skip C++11 attributes that appear in syntactic /// locations where attributes are not allowed. void DiagnoseAndSkipCXX11Attributes(); + /// \brief Parses syntax-generic attribute arguments for attributes which are + /// known to the implementation, and adds them to the given ParsedAttributes + /// list with the given attribute syntax. Returns the number of arguments + /// parsed for the attribute. + unsigned + ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, SourceLocation *EndLoc, + IdentifierInfo *ScopeName, SourceLocation ScopeLoc, + AttributeList::Syntax Syntax); + void MaybeParseGNUAttributes(Declarator &D, - LateParsedAttrList *LateAttrs = 0) { + LateParsedAttrList *LateAttrs = nullptr) { if (Tok.is(tok::kw___attribute)) { ParsedAttributes attrs(AttrFactory); SourceLocation endLoc; - ParseGNUAttributes(attrs, &endLoc, LateAttrs); + ParseGNUAttributes(attrs, &endLoc, LateAttrs, &D); D.takeAttributes(attrs, endLoc); } } void MaybeParseGNUAttributes(ParsedAttributes &attrs, - SourceLocation *endLoc = 0, - LateParsedAttrList *LateAttrs = 0) { + SourceLocation *endLoc = nullptr, + LateParsedAttrList *LateAttrs = nullptr) { if (Tok.is(tok::kw___attribute)) ParseGNUAttributes(attrs, endLoc, LateAttrs); } void ParseGNUAttributes(ParsedAttributes &attrs, - SourceLocation *endLoc = 0, - LateParsedAttrList *LateAttrs = 0); + SourceLocation *endLoc = nullptr, + LateParsedAttrList *LateAttrs = nullptr, + Declarator *D = nullptr); void ParseGNUAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName, SourceLocation ScopeLoc, - AttributeList::Syntax Syntax); + AttributeList::Syntax Syntax, + Declarator *D); IdentifierLoc *ParseIdentifierLoc(); void MaybeParseCXX11Attributes(Declarator &D) { @@ -1943,7 +2067,7 @@ private: } } void MaybeParseCXX11Attributes(ParsedAttributes &attrs, - SourceLocation *endLoc = 0) { + SourceLocation *endLoc = nullptr) { if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) { ParsedAttributesWithRange attrsWithRange(AttrFactory); ParseCXX11Attributes(attrsWithRange, endLoc); @@ -1951,7 +2075,7 @@ private: } } void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs, - SourceLocation *endLoc = 0, + SourceLocation *endLoc = nullptr, bool OuterMightBeMessageSend = false) { if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) @@ -1959,54 +2083,68 @@ private: } void ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, - SourceLocation *EndLoc = 0); + SourceLocation *EndLoc = nullptr); void ParseCXX11Attributes(ParsedAttributesWithRange &attrs, - SourceLocation *EndLoc = 0); + SourceLocation *EndLoc = nullptr); + /// \brief Parses a C++-style attribute argument list. Returns true if this + /// results in adding an attribute to the ParsedAttributes list. + bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs, SourceLocation *EndLoc, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc); IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc); void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs, - SourceLocation *endLoc = 0) { + SourceLocation *endLoc = nullptr) { if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square)) ParseMicrosoftAttributes(attrs, endLoc); } void ParseMicrosoftAttributes(ParsedAttributes &attrs, - SourceLocation *endLoc = 0); + SourceLocation *endLoc = nullptr); void ParseMicrosoftDeclSpec(ParsedAttributes &Attrs); - bool IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident); - void ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident, - SourceLocation Loc, - ParsedAttributes &Attrs); - void ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName, - SourceLocation AttrNameLoc, - ParsedAttributes &Attrs); + bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName, + SourceLocation AttrNameLoc, + ParsedAttributes &Attrs); void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs); void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs); void ParseBorlandTypeAttributes(ParsedAttributes &attrs); void ParseOpenCLAttributes(ParsedAttributes &attrs); - void ParseOpenCLQualifiers(DeclSpec &DS); + void ParseOpenCLQualifiers(ParsedAttributes &Attrs); VersionTuple ParseVersionTuple(SourceRange &Range); void ParseAvailabilityAttribute(IdentifierInfo &Availability, SourceLocation AvailabilityLoc, ParsedAttributes &attrs, - SourceLocation *endLoc); - - bool IsThreadSafetyAttribute(StringRef AttrName); - void ParseThreadSafetyAttribute(IdentifierInfo &AttrName, - SourceLocation AttrNameLoc, - ParsedAttributes &Attrs, - SourceLocation *EndLoc); + SourceLocation *endLoc, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc, + AttributeList::Syntax Syntax); + + void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated, + SourceLocation ObjCBridgeRelatedLoc, + ParsedAttributes &attrs, + SourceLocation *endLoc, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc, + AttributeList::Syntax Syntax); void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs, - SourceLocation *EndLoc); + SourceLocation *EndLoc, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc, + AttributeList::Syntax Syntax); void ParseAttributeWithTypeArg(IdentifierInfo &AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs, - SourceLocation *EndLoc); + SourceLocation *EndLoc, + IdentifierInfo *ScopeName, + SourceLocation ScopeLoc, + AttributeList::Syntax Syntax); void ParseTypeofSpecifier(DeclSpec &DS); SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); @@ -2019,7 +2157,7 @@ private: ExprResult ParseAlignArgument(SourceLocation Start, SourceLocation &EllipsisLoc); void ParseAlignmentSpecifier(ParsedAttributes &Attrs, - SourceLocation *endLoc = 0); + SourceLocation *endLoc = nullptr); VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const; VirtSpecifiers::Specifier isCXX11VirtSpecifier() const { @@ -2090,6 +2228,7 @@ private: SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo, SourceLocation &EllipsisLoc); void ParseBracketDeclarator(Declarator &D); + void ParseMisplacedBracketDeclarator(Declarator &D); //===--------------------------------------------------------------------===// // C++ 7: Declarations [dcl.dcl] @@ -2123,7 +2262,7 @@ private: const ParsedTemplateInfo &TemplateInfo, SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs, - Decl **OwnedType = 0); + Decl **OwnedType = nullptr); Decl *ParseUsingDirective(unsigned Context, SourceLocation UsingLoc, SourceLocation &DeclEnd, @@ -2133,7 +2272,7 @@ private: SourceLocation UsingLoc, SourceLocation &DeclEnd, AccessSpecifier AS = AS_none, - Decl **OwnedType = 0); + Decl **OwnedType = nullptr); Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd); Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, @@ -2154,9 +2293,13 @@ private: Decl *TagDecl); ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction, SourceLocation &EqualLoc); + void ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo, + VirtSpecifiers &VS, + ExprResult &BitfieldSize, + LateParsedAttrList &LateAttrs); void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), - ParsingDeclRAIIObject *DiagsFromTParams = 0); + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), + ParsingDeclRAIIObject *DiagsFromTParams = nullptr); void ParseConstructorInitializer(Decl *ConstructorDecl); MemInitResult ParseMemInitializer(Decl *ConstructorDecl); void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, @@ -2197,7 +2340,12 @@ private: SmallVectorImpl<Expr *> &VarList, bool AllowScopeSpecifier); /// \brief Parses declarative or executable directive. - StmtResult ParseOpenMPDeclarativeOrExecutableDirective(); + /// + /// \param StandAloneAllowed true if allowed stand-alone directives, + /// false - otherwise + /// + StmtResult + ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed); /// \brief Parses clause of kind \a CKind for directive of a kind \a Kind. /// /// \param DKind Kind of current directive. @@ -2217,6 +2365,17 @@ private: /// \param Kind Kind of current clause. /// OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind); + /// \brief Parses clause with a single expression and an additional argument + /// of a kind \a Kind. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind); + /// \brief Parses clause without any additional arguments. + /// + /// \param Kind Kind of current clause. + /// + OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind); /// \brief Parses clause with the list of variables of a kind \a Kind. /// /// \param Kind Kind of current clause. @@ -2236,9 +2395,9 @@ private: // C++ 14.1: Template Parameters [temp.param] Decl *ParseDeclarationStartingWithTemplate(unsigned Context, - SourceLocation &DeclEnd, - AccessSpecifier AS = AS_none, - AttributeList *AccessAttrs = 0); + SourceLocation &DeclEnd, + AccessSpecifier AS = AS_none, + AttributeList *AccessAttrs = nullptr); Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context, SourceLocation &DeclEnd, AccessSpecifier AS, @@ -2249,7 +2408,7 @@ private: ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd, AccessSpecifier AS=AS_none, - AttributeList *AccessAttrs = 0); + AttributeList *AccessAttrs = nullptr); bool ParseTemplateParameters(unsigned Depth, SmallVectorImpl<Decl*> &TemplateParams, SourceLocation &LAngleLoc, @@ -2261,6 +2420,12 @@ private: Decl *ParseTypeParameter(unsigned Depth, unsigned Position); Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position); Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position); + void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc, + SourceLocation CorrectLoc, + bool AlreadyHasEllipsis, + bool IdentifierHasName); + void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc, + Declarator &D); // C++ 14.3: Template arguments [temp.arg] typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList; @@ -2295,9 +2460,7 @@ private: DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc); //===--------------------------------------------------------------------===// - // GNU G++: Type Traits [Type-Traits.html in the GCC manual] - ExprResult ParseUnaryTypeTrait(); - ExprResult ParseBinaryTypeTrait(); + // C++11/G++: Type Traits [Type-Traits.html in the GCC manual] ExprResult ParseTypeTrait(); //===--------------------------------------------------------------------===// @@ -2307,14 +2470,13 @@ private: //===--------------------------------------------------------------------===// // Preprocessor code-completion pass-through - virtual void CodeCompleteDirective(bool InConditional); - virtual void CodeCompleteInConditionalExclusion(); - virtual void CodeCompleteMacroName(bool IsDefinition); - virtual void CodeCompletePreprocessorExpression(); - virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro, - MacroInfo *MacroInfo, - unsigned ArgumentIndex); - virtual void CodeCompleteNaturalLanguage(); + void CodeCompleteDirective(bool InConditional) override; + void CodeCompleteInConditionalExclusion() override; + void CodeCompleteMacroName(bool IsDefinition) override; + void CodeCompletePreprocessorExpression() override; + void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo, + unsigned ArgumentIndex) override; + void CodeCompleteNaturalLanguage() override; }; } // end namespace clang |