diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp | 113 |
1 files changed, 84 insertions, 29 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp index 45878b9..c64b97d 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp @@ -1,4 +1,4 @@ -//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===// +//===--- ParseDecl.cpp - Declaration Parsing --------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -24,9 +24,11 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/SemaDiagnostic.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" + using namespace clang; //===----------------------------------------------------------------------===// @@ -67,7 +69,6 @@ TypeResult Parser::ParseTypeName(SourceRange *Range, return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); } - /// isAttributeLateParsed - Return true if the attribute has arguments that /// require late parsing. static bool isAttributeLateParsed(const IdentifierInfo &II) { @@ -387,7 +388,7 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName, // If the attribute isn't known, we will not attempt to parse any // arguments. if (!hasAttribute(AttrSyntax::Declspec, nullptr, AttrName, - getTargetInfo().getTriple(), getLangOpts())) { + getTargetInfo(), getLangOpts())) { // Eat the left paren, then skip to the ending right paren. ConsumeParen(); SkipUntil(tok::r_paren); @@ -532,9 +533,7 @@ bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName, /// extended-decl-modifier extended-decl-modifier-seq void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs, SourceLocation *End) { - assert((getLangOpts().MicrosoftExt || getLangOpts().Borland || - getLangOpts().CUDA) && - "Incorrect language options for parsing __declspec"); + assert(getLangOpts().DeclSpecKeyword && "__declspec keyword is not enabled"); assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); while (Tok.is(tok::kw___declspec)) { @@ -1155,7 +1154,6 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) { Class.TagOrTemplate); } - /// \brief Parse all attributes in LAs, and attach them to Decl D. void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, bool EnterScope, bool OnDefinition) { @@ -1170,7 +1168,6 @@ void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D, LAs.clear(); } - /// \brief Finish parsing an attribute for which parsing was delayed. /// This will be called at the end of parsing a class declaration /// for each LateParsedAttribute. We consume the saved tokens and @@ -1468,15 +1465,13 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context, if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) { ProhibitAttributes(attrs); SourceLocation InlineLoc = ConsumeToken(); - SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); - break; + return ParseNamespace(Context, DeclEnd, InlineLoc); } return ParseSimpleDeclaration(Context, DeclEnd, attrs, true); case tok::kw_namespace: ProhibitAttributes(attrs); - SingleDecl = ParseNamespace(Context, DeclEnd); - break; + return ParseNamespace(Context, DeclEnd); case tok::kw_using: SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(), DeclEnd, attrs, &OwnedType); @@ -1979,8 +1974,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes( // Recover as if it were an explicit specialization. TemplateParameterLists FakedParamLists; FakedParamLists.push_back(Actions.ActOnTemplateParameterList( - 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, nullptr, - 0, LAngleLoc)); + 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None, + LAngleLoc)); ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D); @@ -2161,7 +2156,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS, DS.ClearStorageClassSpecs(); } - // Issue diagnostic and remove function specfier if present. + // Issue diagnostic and remove function specifier if present. if (Specs & DeclSpec::PQ_FunctionSpecifier) { if (DS.isInlineSpecified()) Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec); @@ -2203,7 +2198,6 @@ static bool isValidAfterIdentifierInDeclarator(const Token &T) { tok::colon); } - /// ParseImplicitInt - This method is called when we have an non-typename /// identifier in a declspec (which normally terminates the decl spec) when /// the declspec has no type specifier. In this case, the declspec is either @@ -2621,8 +2615,6 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, /// [OpenCL] '__kernel' /// 'friend': [C++ dcl.friend] /// 'constexpr': [C++0x dcl.constexpr] - -/// void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS, @@ -2647,6 +2639,18 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, const char *PrevSpec = nullptr; unsigned DiagID = 0; + // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL + // implementation for VS2013 uses _Atomic as an identifier for one of the + // classes in <atomic>. + // + // A typedef declaration containing _Atomic<...> is among the places where + // the class is used. If we are currently parsing such a declaration, treat + // the token as an identifier. + if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) && + DS.getStorageClassSpec() == clang::DeclSpec::SCS_typedef && + !DS.hasTypeSpecifier() && GetLookAheadToken(1).is(tok::less)) + Tok.setKind(tok::identifier); + SourceLocation Loc = Tok.getLocation(); switch (Tok.getKind()) { @@ -2665,7 +2669,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // If this is not a declaration specifier token, we're done reading decl // specifiers. First verify that DeclSpec's are consistent. - DS.Finish(Diags, PP, Policy); + DS.Finish(Actions, Policy); return; case tok::l_square: @@ -2780,8 +2784,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // arguments. Complain, then parse it as a type as the user // intended. Diag(TemplateId->TemplateNameLoc, - diag::err_out_of_line_template_id_names_constructor) - << TemplateId->Name; + diag::err_out_of_line_template_id_type_names_constructor) + << TemplateId->Name << 0 /* template name */; } DS.getTypeSpecScope() = SS; @@ -2826,8 +2830,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, // looked at the declarator, and the user probably meant this // to be a type. Complain that it isn't supposed to be treated // as a type, then proceed to parse it as a type. - Diag(Next.getLocation(), diag::err_out_of_line_type_names_constructor) - << Next.getIdentifierInfo(); + Diag(Next.getLocation(), + diag::err_out_of_line_template_id_type_names_constructor) + << Next.getIdentifierInfo() << 1 /* type */; } ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), @@ -3133,6 +3138,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, PrevSpec, DiagID, Policy); isStorageClass = true; break; + case tok::kw___auto_type: + Diag(Tok, diag::ext_auto_type); + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto_type, Loc, PrevSpec, + DiagID, Policy); + break; case tok::kw_register: isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc, PrevSpec, DiagID, Policy); @@ -3316,6 +3326,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::kw___bool: isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw_pipe: + if (!getLangOpts().OpenCL || (getLangOpts().OpenCLVersion < 200)) { + // OpenCL 2.0 defined this keyword. OpenCL 1.2 and earlier should + // support the "pipe" word as identifier. + Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); + goto DoneWithDeclSpec; + } + isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy); + break; case tok::kw___unknown_anytype: isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, PrevSpec, DiagID, Policy); @@ -3577,7 +3596,8 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, SmallVector<Decl *, 32> FieldDecls; // While we still have something to read, read the declarations in the struct. - while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { + while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) && + Tok.isNot(tok::eof)) { // Each iteration of this loop reads one struct-declaration. // Check for extraneous top-level semicolon. @@ -4390,6 +4410,9 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { switch (Tok.getKind()) { default: return false; + case tok::kw_pipe: + return getLangOpts().OpenCL && (getLangOpts().OpenCLVersion >= 200); + case tok::identifier: // foo::bar // Unfortunate hack to support "Class.factoryMethod" notation. if (getLangOpts().ObjC1 && NextToken().is(tok::period)) @@ -4434,6 +4457,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::kw___private_extern__: case tok::kw_static: case tok::kw_auto: + case tok::kw___auto_type: case tok::kw_register: case tok::kw___thread: case tok::kw_thread_local: @@ -4807,7 +4831,7 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs, DoneWithTypeQuals: // If this is not a type-qualifier token, we're done reading type // qualifiers. First verify that DeclSpec's are consistent. - DS.Finish(Diags, PP, Actions.getASTContext().getPrintingPolicy()); + DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy()); if (EndLoc.isValid()) DS.SetRangeEnd(EndLoc); return; @@ -4822,7 +4846,6 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs, } } - /// ParseDeclarator - Parse and verify a newly-initialized declarator. /// void Parser::ParseDeclarator(Declarator &D) { @@ -4836,6 +4859,9 @@ static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, if (Kind == tok::star || Kind == tok::caret) return true; + if ((Kind == tok::kw_pipe) && Lang.OpenCL && (Lang.OpenCLVersion >= 200)) + return true; + if (!Lang.CPlusPlus) return false; @@ -4854,6 +4880,17 @@ static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, return false; } +// Indicates whether the given declarator is a pipe declarator. +static bool isPipeDeclerator(const Declarator &D) { + const unsigned NumTypes = D.getNumTypeObjects(); + + for (unsigned Idx = 0; Idx != NumTypes; ++Idx) + if (DeclaratorChunk::Pipe == D.getTypeObject(Idx).Kind) + return true; + + return false; +} + /// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator /// is parsed by the function passed to it. Pass null, and the direct-declarator /// isn't parsed at all, making this function effectively parse the C++ @@ -4930,6 +4967,15 @@ void Parser::ParseDeclaratorInternal(Declarator &D, } tok::TokenKind Kind = Tok.getKind(); + + if (D.getDeclSpec().isTypeSpecPipe() && !isPipeDeclerator(D)) { + DeclSpec &DS = D.getMutableDeclSpec(); + + D.AddTypeInfo( + DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()), + DS.getAttributes(), SourceLocation()); + } + // Not a pointer, C++ reference, or block. if (!isPtrOperatorToken(Kind, getLangOpts(), D.getContext())) { if (DirectDeclParser) @@ -5187,6 +5233,15 @@ void Parser::ParseDirectDeclarator(Declarator &D) { } goto PastIdentifier; } + + if (D.getCXXScopeSpec().isNotEmpty()) { + // We have a scope specifier but no following unqualified-id. + Diag(PP.getLocForEndOfToken(D.getCXXScopeSpec().getEndLoc()), + diag::err_expected_unqualified_id) + << /*C++*/1; + D.SetIdentifier(nullptr, Tok.getLocation()); + goto PastIdentifier; + } } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) { assert(!getLangOpts().CPlusPlus && "There's a C++-specific check for tok::identifier above"); @@ -5470,7 +5525,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, SmallVector<ParsedType, 2> DynamicExceptions; SmallVector<SourceRange, 2> DynamicExceptionRanges; ExprResult NoexceptExpr; - CachedTokens *ExceptionSpecTokens = 0; + CachedTokens *ExceptionSpecTokens = nullptr; ParsedAttributes FnAttrs(AttrFactory); TypeResult TrailingReturnType; @@ -5608,7 +5663,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D, VolatileQualifierLoc, RestrictQualifierLoc, /*MutableLoc=*/SourceLocation(), - ESpecType, ESpecRange.getBegin(), + ESpecType, ESpecRange, DynamicExceptions.data(), DynamicExceptionRanges.data(), DynamicExceptions.size(), @@ -6072,6 +6127,7 @@ void Parser::ParseMisplacedBracketDeclarator(Declarator &D) { case DeclaratorChunk::Reference: case DeclaratorChunk::BlockPointer: case DeclaratorChunk::MemberPointer: + case DeclaratorChunk::Pipe: NeedParens = true; break; case DeclaratorChunk::Array: @@ -6227,7 +6283,6 @@ void Parser::ParseAtomicSpecifier(DeclSpec &DS) { Diag(StartLoc, DiagID) << PrevSpec; } - /// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called /// from TryAltiVecVectorToken. bool Parser::TryAltiVecVectorTokenOutOfLine() { |