diff options
Diffstat (limited to 'include/clang/Parse/Parser.h')
-rw-r--r-- | include/clang/Parse/Parser.h | 581 |
1 files changed, 363 insertions, 218 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 0046f88..0e5e8c7 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -20,9 +20,10 @@ #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Sema/Sema.h" #include "clang/Sema/DeclSpec.h" -#include "llvm/Support/PrettyStackTrace.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/PrettyStackTrace.h" #include <stack> namespace clang { @@ -36,7 +37,7 @@ namespace clang { class InMessageExpressionRAIIObject; class PoisonSEHIdentifiersRAIIObject; class VersionTuple; - + /// PrettyStackTraceParserEntry - If a crash happens while the parser is active, /// an entry is printed for it. class PrettyStackTraceParserEntry : public llvm::PrettyStackTraceEntry { @@ -96,7 +97,7 @@ class Parser : public CodeCompletionHandler { unsigned short ParenCount, BracketCount, BraceCount; /// Actions - These are the callbacks we invoke as we parse various constructs - /// in the file. + /// in the file. Sema &Actions; DiagnosticsEngine &Diags; @@ -108,9 +109,21 @@ class Parser : public CodeCompletionHandler { /// Identifiers used for SEH handling in Borland. These are only /// allowed in particular circumstances - IdentifierInfo *Ident__exception_code, *Ident___exception_code, *Ident_GetExceptionCode; // __except block - IdentifierInfo *Ident__exception_info, *Ident___exception_info, *Ident_GetExceptionInfo; // __except filter expression - IdentifierInfo *Ident__abnormal_termination, *Ident___abnormal_termination, *Ident_AbnormalTermination; // __finally + // __except block + IdentifierInfo *Ident__exception_code, + *Ident___exception_code, + *Ident_GetExceptionCode; + // __except filter expression + IdentifierInfo *Ident__exception_info, + *Ident___exception_info, + *Ident_GetExceptionInfo; + // __finally + IdentifierInfo *Ident__abnormal_termination, + *Ident___abnormal_termination, + *Ident_AbnormalTermination; + + /// Contextual keywords for Microsoft extensions. + IdentifierInfo *Ident__except; /// Ident_super - IdentifierInfo for "super", to support fast /// comparison. @@ -123,7 +136,7 @@ class Parser : public CodeCompletionHandler { /// Objective-C contextual keywords. mutable IdentifierInfo *Ident_instancetype; - + /// \brief Identifier for "introduced". IdentifierInfo *Ident_introduced; @@ -135,43 +148,47 @@ class Parser : public CodeCompletionHandler { /// \brief Identifier for "unavailable". IdentifierInfo *Ident_unavailable; + + /// \brief Identifier for "message". + IdentifierInfo *Ident_message; - /// C++0x contextual keywords. + /// C++0x contextual keywords. mutable IdentifierInfo *Ident_final; mutable IdentifierInfo *Ident_override; - llvm::OwningPtr<PragmaHandler> AlignHandler; - llvm::OwningPtr<PragmaHandler> GCCVisibilityHandler; - llvm::OwningPtr<PragmaHandler> OptionsHandler; - llvm::OwningPtr<PragmaHandler> PackHandler; - llvm::OwningPtr<PragmaHandler> MSStructHandler; - llvm::OwningPtr<PragmaHandler> UnusedHandler; - llvm::OwningPtr<PragmaHandler> WeakHandler; - llvm::OwningPtr<PragmaHandler> FPContractHandler; - llvm::OwningPtr<PragmaHandler> OpenCLExtensionHandler; + 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; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ /// template argument list, where the '>' closes the template /// argument list. bool GreaterThanIsOperator; - + /// ColonIsSacred - When this is false, we aggressively try to recover from /// code like "foo : bar" as if it were a typo for "foo :: bar". This is not /// safe in case statements and a few other things. This is managed by the /// 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 messsage /// send expression. /// /// This is managed by the \c InMessageExpressionRAIIObject class, and /// should not be set directly. bool InMessageExpression; - + /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; - + /// Factory object for creating AttributeList objects. AttributeFactory AttrFactory; @@ -179,20 +196,24 @@ class Parser : public CodeCompletionHandler { /// declaration is finished. DelayedCleanupPool TopLevelDeclCleanupPool; + IdentifierInfo *getSEHExceptKeyword(); + + bool SkipFunctionBodies; + public: - Parser(Preprocessor &PP, Sema &Actions); + Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies); ~Parser(); - const LangOptions &getLang() const { return PP.getLangOptions(); } + const LangOptions &getLangOpts() const { return PP.getLangOpts(); } const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); } Preprocessor &getPreprocessor() const { return PP; } Sema &getActions() const { return Actions; } const Token &getCurToken() const { return Tok; } Scope *getCurScope() const { return Actions.getCurScope(); } - + Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); } - + // Type forwarding. All of these are statically 'void*', but they may all be // different actual classes based on the actions in place. typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; @@ -241,8 +262,6 @@ public: /// the EOF was encountered. bool ParseTopLevelDecl(DeclGroupPtrTy &Result); - DeclGroupPtrTy FinishPendingObjCActions(); - private: //===--------------------------------------------------------------------===// // Low-Level token peeking and consumption methods. @@ -271,10 +290,9 @@ private: Tok.getKind() == tok::utf32_string_literal; } - /// \brief Returns true if the current token is a '=' or '==' and - /// false otherwise. If it's '==', we assume that it's a typo and we emit - /// DiagID and a fixit hint to turn '==' -> '='. - bool isTokenEqualOrMistypedEqualEqual(unsigned DiagID); + /// \brief Returns true if the current token is '=' or is a type of '='. + /// For typos, give a fixit to '=' + bool isTokenEqualOrEqualTypo(); /// ConsumeToken - Consume the current 'peek token' and lex the next one. /// This does not work with all kinds of tokens: strings and specific other @@ -370,9 +388,9 @@ private: assert(Tok.is(tok::code_completion)); PrevTokLocation = Tok.getLocation(); PP.Lex(Tok); - return PrevTokLocation; + return PrevTokLocation; } - + ///\ brief When we are consuming a code-completion token without having /// matched specific position in the grammar, provide code-completion results /// based on context. @@ -391,6 +409,14 @@ private: /// \brief Handle the annotation token produced for #pragma unused(...) void HandlePragmaUnused(); + /// \brief Handle the annotation token produced for + /// #pragma GCC visibility... + void HandlePragmaVisibility(); + + /// \brief Handle the annotation token produced for + /// #pragma pack... + void HandlePragmaPack(); + /// 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. @@ -409,83 +435,77 @@ private: return PP.LookAhead(0); } - /// \brief Tracks information about the current nesting depth of - /// opening delimiters of each kind. - class DelimiterTracker { - private: - friend class Parser; - - unsigned Paren, Brace, Square, Less, LLLess; - unsigned& get(tok::TokenKind t) { - switch (t) { - default: llvm_unreachable("Unexpected balanced token"); - case tok::l_brace: return Brace; - case tok::l_paren: return Paren; - case tok::l_square: return Square; - case tok::less: return Less; - case tok::lesslessless: return LLLess; - } - } - - void push(tok::TokenKind t) { - get(t)++; - } - - void pop(tok::TokenKind t) { - get(t)--; - } - - unsigned getDepth(tok::TokenKind t) { - return get(t); - } - - public: - DelimiterTracker() : Paren(0), Brace(0), Square(0), Less(0), LLLess(0) { } - }; - /// \brief RAII class that helps handle the parsing of an open/close delimiter /// pair, such as braces { ... } or parentheses ( ... ). class BalancedDelimiterTracker { - tok::TokenKind Kind, Close; Parser& P; - bool Cleanup; - const unsigned MaxDepth; + tok::TokenKind Kind, Close; + SourceLocation (Parser::*Consumer)(); SourceLocation LOpen, LClose; - - void assignClosingDelimiter() { + + unsigned short &getDepth() { switch (Kind) { - default: llvm_unreachable("Unexpected balanced token"); - case tok::l_brace: Close = tok::r_brace; break; - case tok::l_paren: Close = tok::r_paren; break; - case tok::l_square: Close = tok::r_square; break; - case tok::less: Close = tok::greater; break; - case tok::lesslessless: Close = tok::greatergreatergreater; break; + case tok::l_brace: return P.BraceCount; + case tok::l_square: return P.BracketCount; + case tok::l_paren: return P.ParenCount; + default: llvm_unreachable("Wrong token kind"); } } - + + enum { MaxDepth = 256 }; + + bool diagnoseOverflow(); + bool diagnoseMissingClose(); + public: - BalancedDelimiterTracker(Parser& p, tok::TokenKind k) - : Kind(k), P(p), Cleanup(false), MaxDepth(256) { - assignClosingDelimiter(); - } - - ~BalancedDelimiterTracker() { - if (Cleanup) - P.QuantityTracker.pop(Kind); + BalancedDelimiterTracker(Parser& p, tok::TokenKind k) : P(p), Kind(k) { + switch (Kind) { + default: llvm_unreachable("Unexpected balanced token"); + case tok::l_brace: + Close = tok::r_brace; + Consumer = &Parser::ConsumeBrace; + break; + case tok::l_paren: + Close = tok::r_paren; + Consumer = &Parser::ConsumeParen; + break; + + case tok::l_square: + Close = tok::r_square; + Consumer = &Parser::ConsumeBracket; + break; + } } SourceLocation getOpenLocation() const { return LOpen; } SourceLocation getCloseLocation() const { return LClose; } SourceRange getRange() const { return SourceRange(LOpen, LClose); } - bool consumeOpen(); - bool expectAndConsume(unsigned DiagID, - const char *Msg = "", + bool consumeOpen() { + if (!P.Tok.is(Kind)) + return true; + + if (getDepth() < MaxDepth) { + LOpen = (P.*Consumer)(); + return false; + } + + return diagnoseOverflow(); + } + + bool expectAndConsume(unsigned DiagID, + const char *Msg = "", tok::TokenKind SkipToTok = tok::unknown); - bool consumeClose(); - }; + bool consumeClose() { + if (P.Tok.is(Close)) { + LClose = (P.*Consumer)(); + return false; + } - DelimiterTracker QuantityTracker; + return diagnoseMissingClose(); + } + void skipToEnd(); + }; /// getTypeAnnotation - Read a parsed type out of an annotation token. static ParsedType getTypeAnnotation(Token &Tok) { @@ -495,16 +515,16 @@ private: static void setTypeAnnotation(Token &Tok, ParsedType T) { Tok.setAnnotationValue(T.getAsOpaquePtr()); } - + /// \brief Read an already-translated primary expression out of an annotation /// token. static ExprResult getExprAnnotation(Token &Tok) { if (Tok.getAnnotationValue()) return ExprResult((Expr *)Tok.getAnnotationValue()); - + return ExprResult(true); } - + /// \brief Set the primary expression corresponding to the given annotation /// token. static void setExprAnnotation(Token &Tok, ExprResult ER) { @@ -526,11 +546,11 @@ private: bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, bool &isInvalid) { - if (!getLang().AltiVec || + if (!getLangOpts().AltiVec || (Tok.getIdentifierInfo() != Ident_vector && Tok.getIdentifierInfo() != Ident_pixel)) return false; - + return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid); } @@ -538,11 +558,11 @@ private: /// identifier token, replacing it with the non-context-sensitive __vector. /// This returns true if the token was replaced. bool TryAltiVecVectorToken() { - if (!getLang().AltiVec || + if (!getLangOpts().AltiVec || Tok.getIdentifierInfo() != Ident_vector) return false; return TryAltiVecVectorTokenOutOfLine(); } - + bool TryAltiVecVectorTokenOutOfLine(); bool TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, @@ -598,14 +618,14 @@ private: Parser &P; Decl *DC; public: - explicit ObjCDeclContextSwitch(Parser &p) : P(p), + explicit ObjCDeclContextSwitch(Parser &p) : P(p), DC(p.getObjCDeclContext()) { if (DC) - P.Actions.ActOnObjCTemporaryExitContainerContext(); + P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC)); } ~ObjCDeclContextSwitch() { if (DC) - P.Actions.ActOnObjCReenterContainerContext(); + P.Actions.ActOnObjCReenterContainerContext(cast<DeclContext>(DC)); } }; @@ -625,7 +645,7 @@ private: /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior /// to the semicolon, consumes that extra token. bool ExpectAndConsumeSemi(unsigned DiagID); - + //===--------------------------------------------------------------------===// // Scope manipulation @@ -695,6 +715,7 @@ public: private: void SuggestParentheses(SourceLocation Loc, unsigned DK, SourceRange ParenRange); + void CheckNestedObjCContexts(SourceLocation AtLoc); /// SkipUntil - Read tokens until we get to the specified token, then consume /// it (unless DontConsume is true). Because we cannot guarantee that the @@ -706,16 +727,26 @@ private: /// returns false. bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true, bool DontConsume = false, bool StopAtCodeCompletion = false) { - return SkipUntil(&T, 1, StopAtSemi, DontConsume, StopAtCodeCompletion); + return SkipUntil(llvm::makeArrayRef(T), StopAtSemi, DontConsume, + StopAtCodeCompletion); } bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true, bool DontConsume = false, bool StopAtCodeCompletion = false) { tok::TokenKind TokArray[] = {T1, T2}; - return SkipUntil(TokArray, 2, StopAtSemi, DontConsume,StopAtCodeCompletion); + return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); } - bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks, + bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, tok::TokenKind T3, bool StopAtSemi = true, bool DontConsume = false, - bool StopAtCodeCompletion = false); + bool StopAtCodeCompletion = false) { + tok::TokenKind TokArray[] = {T1, T2, T3}; + return SkipUntil(TokArray, StopAtSemi, DontConsume,StopAtCodeCompletion); + } + bool SkipUntil(ArrayRef<tok::TokenKind> Toks, bool StopAtSemi = true, + bool DontConsume = false, bool StopAtCodeCompletion = false); + + /// SkipMalformedDecl - Read tokens until we get to some likely good stopping + /// point for skipping past a simple-declaration. + void SkipMalformedDecl(); //===--------------------------------------------------------------------===// // Lexing and parsing of C++ inline methods. @@ -757,9 +788,9 @@ private: ParsingClass *Class; }; - /// Contains the lexed tokens of an attribute with arguments that - /// may reference member variables and so need to be parsed at the - /// end of the class declaration after parsing all other member + /// Contains the lexed tokens of an attribute with arguments that + /// may reference member variables and so need to be parsed at the + /// end of the class declaration after parsing all other member /// member declarations. /// FIXME: Perhaps we should change the name of LateParsedDeclaration to /// LateParsedTokens. @@ -768,15 +799,15 @@ private: CachedTokens Toks; IdentifierInfo &AttrName; SourceLocation AttrNameLoc; - Decl *D; + SmallVector<Decl*, 2> Decls; - explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name, + explicit LateParsedAttribute(Parser *P, IdentifierInfo &Name, SourceLocation Loc) - : Self(P), AttrName(Name), AttrNameLoc(Loc), D(0) {} + : Self(P), AttrName(Name), AttrNameLoc(Loc) {} virtual void ParseLexedAttributes(); - void setDecl(Decl *Dec) { D = Dec; } + void addDecl(Decl *D) { Decls.push_back(D); } }; /// A list of late parsed attributes. Used by ParseGNUAttributes. @@ -872,8 +903,9 @@ private: /// C++ class, its method declarations that contain parts that won't be /// parsed until after the definition is completed (C++ [class.mem]p2), /// the method declarations and possibly attached inline definitions - /// will be stored here with the tokens that will be parsed to create those entities. - typedef SmallVector<LateParsedDeclaration*, 2> LateParsedDeclarationsContainer; + /// will be stored here with the tokens that will be parsed to create those + /// entities. + typedef SmallVector<LateParsedDeclaration*,2> LateParsedDeclarationsContainer; /// \brief Representation of a class that has been parsed, including /// any member function declarations or definitions that need to be @@ -965,7 +997,7 @@ private: Popped = Other.Popped; Other.Popped = true; } - + void push() { State = Actions.PushParsingDeclaration(); Popped = false; @@ -1060,7 +1092,7 @@ private: bool isSpecialization, bool lastParameterListWasEmpty = false) : Kind(isSpecialization? ExplicitSpecialization : Template), - TemplateParams(TemplateParams), + TemplateParams(TemplateParams), LastParameterListWasEmpty(lastParameterListWasEmpty) { } explicit ParsedTemplateInfo(SourceLocation ExternLoc, @@ -1092,23 +1124,23 @@ private: /// \brief The location of the 'template' keyword, for an explicit /// instantiation. SourceLocation TemplateLoc; - + /// \brief Whether the last template parameter list was empty. bool LastParameterListWasEmpty; - SourceRange getSourceRange() const; + 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(Parser* P, Decl *MD) + explicit LateParsedTemplatedFunction(Decl *MD) : D(MD) {} CachedTokens Toks; - + /// \brief The template function declaration to be late parsed. - Decl *D; + Decl *D; }; void LexTemplateFunctionForLateParsing(CachedTokens &Toks); @@ -1128,10 +1160,15 @@ private: Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, AttributeList *AccessAttrs, ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, - const VirtSpecifiers& VS, ExprResult& Init); + const VirtSpecifiers& VS, + FunctionDefinitionKind DefinitionKind, + ExprResult& Init); void ParseCXXNonStaticMemberInitializer(Decl *VarD); void ParseLexedAttributes(ParsingClass &Class); - void ParseLexedAttribute(LateParsedAttribute &LA); + void ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, + bool EnterScope, bool OnDefinition); + void ParseLexedAttribute(LateParsedAttribute &LA, + bool EnterScope, bool OnDefinition); void ParseLexedMethodDeclarations(ParsingClass &Class); void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM); void ParseLexedMethodDefs(ParsingClass &Class); @@ -1168,9 +1205,10 @@ private: AccessSpecifier AS = AS_none); DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS, AccessSpecifier AS = AS_none); - + Decl *ParseFunctionDefinition(ParsingDeclarator &D, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), + LateParsedAttrList *LateParsedAttrs = 0); void ParseKNRParamDeclarations(Declarator &D); // EndLoc, if non-NULL, is filled with the location of the last token of // the simple-asm. @@ -1178,9 +1216,9 @@ private: ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations - Parser::DeclGroupPtrTy ParseObjCAtDirectives(); - Parser::DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); - Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, + DeclGroupPtrTy ParseObjCAtDirectives(); + DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); + Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, ParsedAttributes &prefixAttrs); void ParseObjCClassInstanceVariables(Decl *interfaceDecl, tok::ObjCKeywordKind visibility, @@ -1193,15 +1231,31 @@ private: bool ParseObjCProtocolQualifiers(DeclSpec &DS); void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, Decl *CDecl); - Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc, - ParsedAttributes &prefixAttrs); + DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc, + ParsedAttributes &prefixAttrs); + + struct ObjCImplParsingDataRAII { + Parser &P; + Decl *Dcl; + typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer; + LateParsedObjCMethodContainer LateParsedObjCMethods; + + ObjCImplParsingDataRAII(Parser &parser, Decl *D) + : P(parser), Dcl(D) { + P.CurParsedObjCImpl = this; + Finished = false; + } + ~ObjCImplParsingDataRAII(); - Decl *ObjCImpDecl; - SmallVector<Decl *, 4> PendingObjCImpDecl; - typedef SmallVector<LexedMethod*, 2> LateParsedObjCMethodContainer; - LateParsedObjCMethodContainer LateParsedObjCMethods; + void finish(SourceRange AtEnd); + bool isFinished() const { return Finished; } + + private: + bool Finished; + }; + ObjCImplParsingDataRAII *CurParsedObjCImpl; - Decl *ParseObjCAtImplementationDeclaration(SourceLocation atLoc); + DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc); DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd); Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc); Decl *ParseObjCPropertySynthesize(SourceLocation atLoc); @@ -1232,11 +1286,18 @@ private: //===--------------------------------------------------------------------===// // C99 6.5: Expressions. - - ExprResult ParseExpression(); - ExprResult ParseConstantExpression(); + + /// TypeCastState - State whether an expression is or may be a type cast. + enum TypeCastState { + NotTypeCast = 0, + MaybeTypeCast, + IsTypeCast + }; + + ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast); + ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast); // Expr that doesn't include commas. - ExprResult ParseAssignmentExpression(); + ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast); ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc); @@ -1247,10 +1308,10 @@ private: ExprResult ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, bool &NotCastExpr, - bool isTypeCast); + TypeCastState isTypeCast); ExprResult ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand = false, - bool isTypeCast = false); + TypeCastState isTypeCast = NotTypeCast); /// Returns true if the next token would start a postfix-expression /// suffix. @@ -1278,8 +1339,7 @@ private: SmallVectorImpl<SourceLocation> &CommaLocs, void (Sema::*Completer)(Scope *S, Expr *Data, - Expr **Args, - unsigned NumArgs) = 0, + llvm::ArrayRef<Expr *> Args) = 0, Expr *Data = 0); /// ParenParseOption - Control what ParseParenExpression will parse. @@ -1302,9 +1362,11 @@ private: SourceLocation LParenLoc, SourceLocation RParenLoc); - ExprResult ParseStringLiteralExpression(); + ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false); ExprResult ParseGenericSelectionExpression(); + + ExprResult ParseObjCBoolLiteral(); //===--------------------------------------------------------------------===// // C++ Expressions @@ -1420,6 +1482,7 @@ private: return ParseAssignmentExpression(); return ParseBraceInitializer(); } + bool MayBeDesignationStart(); ExprResult ParseBraceInitializer(); ExprResult ParseInitializerWithPotentialDesignator(); @@ -1432,29 +1495,35 @@ private: // Objective-C Expressions ExprResult ParseObjCAtExpression(SourceLocation AtLocation); ExprResult ParseObjCStringLiteral(SourceLocation AtLoc); + ExprResult ParseObjCCharacterLiteral(SourceLocation AtLoc); + ExprResult ParseObjCNumericLiteral(SourceLocation AtLoc); + ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue); + ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc); + ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc); ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc); ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc); ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc); bool isSimpleObjCMessageExpression(); ExprResult ParseObjCMessageExpression(); ExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc, - SourceLocation SuperLoc, - ParsedType ReceiverType, - ExprArg ReceiverExpr); + SourceLocation SuperLoc, + ParsedType ReceiverType, + ExprArg ReceiverExpr); ExprResult ParseAssignmentExprWithObjCMessageExprStart( SourceLocation LBracloc, SourceLocation SuperLoc, ParsedType ReceiverType, ExprArg ReceiverExpr); bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr); - + //===--------------------------------------------------------------------===// // C99 6.8: Statements and Blocks. - StmtResult ParseStatement() { + StmtResult ParseStatement(SourceLocation *TrailingElseLoc = NULL) { StmtVector Stmts(Actions); - return ParseStatementOrDeclaration(Stmts, true); + return ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc); } StmtResult ParseStatementOrDeclaration(StmtVector& Stmts, - bool OnlyStatement = false); + bool OnlyStatement, + SourceLocation *TrailingElseLoc = NULL); StmtResult ParseExprStatement(ParsedAttributes &Attrs); StmtResult ParseLabeledStatement(ParsedAttributes &Attr); StmtResult ParseCaseStatement(ParsedAttributes &Attr, @@ -1471,22 +1540,61 @@ private: Decl *&DeclResult, SourceLocation Loc, bool ConvertToBoolean); - StmtResult ParseIfStatement(ParsedAttributes &Attr); - StmtResult ParseSwitchStatement(ParsedAttributes &Attr); - StmtResult ParseWhileStatement(ParsedAttributes &Attr); + StmtResult ParseIfStatement(ParsedAttributes &Attr, + SourceLocation *TrailingElseLoc); + StmtResult ParseSwitchStatement(ParsedAttributes &Attr, + SourceLocation *TrailingElseLoc); + StmtResult ParseWhileStatement(ParsedAttributes &Attr, + SourceLocation *TrailingElseLoc); StmtResult ParseDoStatement(ParsedAttributes &Attr); - StmtResult ParseForStatement(ParsedAttributes &Attr); + StmtResult ParseForStatement(ParsedAttributes &Attr, + SourceLocation *TrailingElseLoc); StmtResult ParseGotoStatement(ParsedAttributes &Attr); StmtResult ParseContinueStatement(ParsedAttributes &Attr); StmtResult ParseBreakStatement(ParsedAttributes &Attr); StmtResult ParseReturnStatement(ParsedAttributes &Attr); StmtResult ParseAsmStatement(bool &msAsm); StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc); - bool ParseMicrosoftIfExistsCondition(bool& Result); + + /// \brief Describes the behavior that should be taken for an __if_exists + /// block. + enum IfExistsBehavior { + /// \brief Parse the block; this code is always used. + IEB_Parse, + /// \brief Skip the block entirely; this code is never used. + IEB_Skip, + /// \brief Parse the block as a dependent block, which may be used in + /// some template instantiations but not others. + IEB_Dependent + }; + + /// \brief Describes the condition of a Microsoft __if_exists or + /// __if_not_exists block. + struct IfExistsCondition { + /// \brief The location of the initial keyword. + SourceLocation KeywordLoc; + /// \brief Whether this is an __if_exists block (rather than an + /// __if_not_exists block). + bool IsIfExists; + + /// \brief Nested-name-specifier preceding the name. + CXXScopeSpec SS; + + /// \brief The name we're looking for. + UnqualifiedId Name; + + /// \brief The behavior of this __if_exists or __if_not_exists block + /// should. + IfExistsBehavior Behavior; +}; + + bool ParseMicrosoftIfExistsCondition(IfExistsCondition& Result); void ParseMicrosoftIfExistsStatement(StmtVector &Stmts); void ParseMicrosoftIfExistsExternalDeclaration(); void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, AccessSpecifier& CurAS); + bool ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs, + bool &InitExprsOk); bool ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names, SmallVectorImpl<Expr *> &Constraints, SmallVectorImpl<Expr *> &Exprs); @@ -1525,6 +1633,8 @@ private: enum DeclSpecContext { DSC_normal, // normal context DSC_class, // class context, enables 'friend' + DSC_type_specifier, // C++ type-specifier-seq + DSC_trailing, // C++11 trailing-type-specifier in a trailing return type DSC_top_level // top-level/namespace declaration context }; @@ -1546,13 +1656,14 @@ private: ParsedAttributes &attrs, bool RequireSemi, ForRangeInit *FRI = 0); + bool MightBeDeclarator(unsigned Context); DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context, bool AllowFunctionDefinitions, SourceLocation *DeclEnd = 0, ForRangeInit *FRI = 0); Decl *ParseDeclarationAfterDeclarator(Declarator &D, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); - bool ParseAttributesAfterDeclarator(Declarator &D); + bool ParseAsmAttributesAfterDeclarator(Declarator &D); Decl *ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo()); Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope); @@ -1562,30 +1673,27 @@ private: /// unless the body contains the code-completion point. /// /// \returns true if the function body was skipped. - bool trySkippingFunctionBodyForCodeCompletion(); + bool trySkippingFunctionBody(); bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, const ParsedTemplateInfo &TemplateInfo, - AccessSpecifier AS); + AccessSpecifier AS, DeclSpecContext DSC); DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context); void ParseDeclarationSpecifiers(DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), AccessSpecifier AS = AS_none, - DeclSpecContext DSC = DSC_normal); - bool ParseOptionalTypeSpecifier(DeclSpec &DS, bool &isInvalid, - const char *&PrevSpec, - unsigned &DiagID, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), - bool SuppressDeclarations = false); + DeclSpecContext DSC = DSC_normal, + LateParsedAttrList *LateAttrs = 0); - void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none); + void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none, + DeclSpecContext DSC = DSC_normal); void ParseObjCTypeQualifierList(ObjCDeclSpec &DS, Declarator::TheContext Context); void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), - AccessSpecifier AS = AS_none); + const ParsedTemplateInfo &TemplateInfo, + AccessSpecifier AS, DeclSpecContext DSC); void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl); void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType, Decl *TagDecl); @@ -1604,7 +1712,7 @@ private: bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false); bool isTypeSpecifierQualifier(); bool isTypeQualifier() const; - + /// isKnownToBeTypeSpecifier - Return true if we know that the specified token /// is definitely a type-specifier. Return false if it isn't part of a type /// specifier or if we're not sure. @@ -1614,25 +1722,25 @@ private: /// expression statement, when parsing function bodies. /// Returns true for declaration, false for expression. bool isDeclarationStatement() { - if (getLang().CPlusPlus) + if (getLangOpts().CPlusPlus) return isCXXDeclarationStatement(); return isDeclarationSpecifier(true); } - /// isSimpleDeclaration - Disambiguates between a declaration or an - /// expression, mainly used for the C 'clause-1' or the C++ + /// isForInitDeclaration - Disambiguates between a declaration or an + /// expression in the context of the C 'clause-1' or the C++ // 'for-init-statement' part of a 'for' statement. /// Returns true for declaration, false for expression. - bool isSimpleDeclaration() { - if (getLang().CPlusPlus) - return isCXXSimpleDeclaration(); + bool isForInitDeclaration() { + if (getLangOpts().CPlusPlus) + return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true); return isDeclarationSpecifier(true); } /// \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(); - + /// \brief Starting with a scope specifier, identifier, or /// template-id that refers to the current class, determine whether /// this is a constructor declarator. @@ -1650,7 +1758,7 @@ private: /// whether the parens contain an expression or a type-id. /// Returns true for a type-id and false for an expression. bool isTypeIdInParens(bool &isAmbiguous) { - if (getLang().CPlusPlus) + if (getLangOpts().CPlusPlus) return isCXXTypeId(TypeIdInParens, isAmbiguous); isAmbiguous = false; return isTypeSpecifierQualifier(); @@ -1670,7 +1778,7 @@ private: /// If during the disambiguation process a parsing error is encountered, /// the function returns true to let the declaration parsing code handle it. /// Returns false if the statement is disambiguated as expression. - bool isCXXSimpleDeclaration(); + bool isCXXSimpleDeclaration(bool AllowForRangeDecl); /// isCXXFunctionDeclarator - Disambiguates between a function declarator or /// a constructor-style initializer, when parsing declaration statements. @@ -1732,10 +1840,12 @@ private: /// 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. + /// encountered. If it could be a braced C++11 function-style cast, returns + /// BracedCastResult. /// Doesn't consume tokens. - TPResult isCXXDeclarationSpecifier(); - + TPResult + isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False()); + // "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 @@ -1744,7 +1854,7 @@ private: // They all consume tokens, so backtracking should be used after calling them. TPResult TryParseDeclarationSpecifier(); - TPResult TryParseSimpleDeclaration(); + TPResult TryParseSimpleDeclaration(bool AllowForRangeDecl); TPResult TryParseTypeofSpecifier(); TPResult TryParseProtocolQualifiers(); TPResult TryParseInitDeclaratorList(); @@ -1760,6 +1870,16 @@ private: Decl **OwnedType = 0); void ParseBlockId(); + // Check for the start of a C++11 attribute-specifier-seq in a context where + // an attribute is not allowed. + bool CheckProhibitedCXX11Attribute() { + assert(Tok.is(tok::l_square)); + if (!getLangOpts().CPlusPlus0x || NextToken().isNot(tok::l_square)) + return false; + return DiagnoseProhibitedCXX11Attribute(); + } + bool DiagnoseProhibitedCXX11Attribute(); + void ProhibitAttributes(ParsedAttributesWithRange &attrs) { if (!attrs.Range.isValid()) return; DiagnoseProhibitedAttributes(attrs); @@ -1790,35 +1910,38 @@ private: SourceLocation *EndLoc); void MaybeParseCXX0XAttributes(Declarator &D) { - if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) { + if (getLangOpts().CPlusPlus0x && isCXX11AttributeSpecifier()) { ParsedAttributesWithRange attrs(AttrFactory); SourceLocation endLoc; - ParseCXX0XAttributes(attrs, &endLoc); + ParseCXX11Attributes(attrs, &endLoc); D.takeAttributes(attrs, endLoc); } } void MaybeParseCXX0XAttributes(ParsedAttributes &attrs, SourceLocation *endLoc = 0) { - if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) { + if (getLangOpts().CPlusPlus0x && isCXX11AttributeSpecifier()) { ParsedAttributesWithRange attrsWithRange(AttrFactory); - ParseCXX0XAttributes(attrsWithRange, endLoc); + ParseCXX11Attributes(attrsWithRange, endLoc); attrs.takeAllFrom(attrsWithRange); } } void MaybeParseCXX0XAttributes(ParsedAttributesWithRange &attrs, - SourceLocation *endLoc = 0) { - if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) - ParseCXX0XAttributes(attrs, endLoc); + SourceLocation *endLoc = 0, + bool OuterMightBeMessageSend = false) { + if (getLangOpts().CPlusPlus0x && + isCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) + ParseCXX11Attributes(attrs, endLoc); } - void ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs, + void ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, SourceLocation *EndLoc = 0); - void ParseCXX0XAttributes(ParsedAttributesWithRange &attrs, + void ParseCXX11Attributes(ParsedAttributesWithRange &attrs, SourceLocation *EndLoc = 0); + IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc); void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs, SourceLocation *endLoc = 0) { - if (getLang().MicrosoftExt && Tok.is(tok::l_square)) + if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square)) ParseMicrosoftAttributes(attrs, endLoc); } void ParseMicrosoftAttributes(ParsedAttributes &attrs, @@ -1843,15 +1966,22 @@ private: void ParseTypeofSpecifier(DeclSpec &DS); - void ParseDecltypeSpecifier(DeclSpec &DS); + SourceLocation ParseDecltypeSpecifier(DeclSpec &DS); + void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS, + SourceLocation StartLoc, + SourceLocation EndLoc); void ParseUnderlyingTypeSpecifier(DeclSpec &DS); void ParseAtomicSpecifier(DeclSpec &DS); - ExprResult ParseAlignArgument(SourceLocation Start); + ExprResult ParseAlignArgument(SourceLocation Start, + SourceLocation &EllipsisLoc); void ParseAlignmentSpecifier(ParsedAttributes &Attrs, SourceLocation *endLoc = 0); - VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const; + VirtSpecifiers::Specifier isCXX0XVirtSpecifier(const Token &Tok) const; + VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const { + return isCXX0XVirtSpecifier(Tok); + } void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS); bool isCXX0XFinalKeyword() const; @@ -1918,9 +2048,20 @@ private: //===--------------------------------------------------------------------===// // C++ 7: Declarations [dcl.dcl] - bool isCXX0XAttributeSpecifier(bool FullLookahead = false, - tok::TokenKind *After = 0); - + /// The kind of attribute specifier we have found. + enum CXX11AttributeKind { + /// This is not an attribute specifier. + CAK_NotAttributeSpecifier, + /// This should be treated as an attribute-specifier. + CAK_AttributeSpecifier, + /// The next tokens are '[[', but this is not an attribute-specifier. This + /// is ill-formed by C++11 [dcl.attr.grammar]p6. + CAK_InvalidAttributeSpecifier + }; + CXX11AttributeKind + isCXX11AttributeSpecifier(bool Disambiguate = false, + bool OuterMightBeMessageSend = false); + Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd, SourceLocation InlineLoc = SourceLocation()); void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, @@ -1952,15 +2093,13 @@ private: //===--------------------------------------------------------------------===// // C++ 9: classes [class] and C structs/unions. - TypeResult ParseClassName(SourceLocation &EndLocation, CXXScopeSpec &SS); void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc, - DeclSpec &DS, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), - AccessSpecifier AS = AS_none, - bool SuppressDeclarations = false); + DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, + AccessSpecifier AS, bool EnteringContext, + DeclSpecContext DSC); void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType, Decl *TagDecl); - ExprResult ParseCXXMemberInitializer(bool IsFunction, + ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction, SourceLocation &EqualLoc); void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), @@ -1972,18 +2111,20 @@ private: //===--------------------------------------------------------------------===// // C++ 10: Derived classes [class.derived] + TypeResult ParseBaseTypeSpecifier(SourceLocation &BaseLoc, + SourceLocation &EndLocation); void ParseBaseClause(Decl *ClassDecl); BaseResult ParseBaseSpecifier(Decl *ClassDecl); AccessSpecifier getAccessSpecifierIfPresent() const; - bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, + bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc, bool EnteringContext, ParsedType ObjectType, UnqualifiedId &Id, - bool AssumeTemplateId, - SourceLocation TemplateKWLoc); + bool AssumeTemplateId); bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, ParsedType ObjectType, UnqualifiedId &Result); @@ -1991,8 +2132,9 @@ private: bool AllowDestructorName, bool AllowConstructorName, ParsedType ObjectType, + SourceLocation& TemplateKWLoc, UnqualifiedId &Result); - + //===--------------------------------------------------------------------===// // C++ 14: Templates [temp] @@ -2036,27 +2178,30 @@ private: bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &TemplateName, - SourceLocation TemplateKWLoc = SourceLocation(), bool AllowTypeAnnotation = true); void AnnotateTemplateIdTokenAsType(); bool IsTemplateArgumentList(unsigned Skip = 0); bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); ParsedTemplateArgument ParseTemplateTemplateArgument(); ParsedTemplateArgument ParseTemplateArgument(); - Decl *ParseExplicitInstantiation(SourceLocation ExternLoc, - SourceLocation TemplateLoc, - SourceLocation &DeclEnd); + Decl *ParseExplicitInstantiation(unsigned Context, + SourceLocation ExternLoc, + SourceLocation TemplateLoc, + SourceLocation &DeclEnd, + AccessSpecifier AS = AS_none); //===--------------------------------------------------------------------===// // Modules - DeclGroupPtrTy ParseModuleImport(); - + DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc); + //===--------------------------------------------------------------------===// // GNU G++: Type Traits [Type-Traits.html in the GCC manual] ExprResult ParseUnaryTypeTrait(); ExprResult ParseBinaryTypeTrait(); - + ExprResult ParseTypeTrait(); + //===--------------------------------------------------------------------===// // Embarcadero: Arary and Expression Traits ExprResult ParseArrayTypeTrait(); |