diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/Parser.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Parse/Parser.cpp | 137 |
1 files changed, 106 insertions, 31 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp index 7ccd209..0574a63 100644 --- a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp @@ -38,6 +38,26 @@ public: return false; } }; + +/// \brief RAIIObject to destroy the contents of a SmallVector of +/// TemplateIdAnnotation pointers and clear the vector. +class DestroyTemplateIdAnnotationsRAIIObj { + SmallVectorImpl<TemplateIdAnnotation *> &Container; + +public: + DestroyTemplateIdAnnotationsRAIIObj( + SmallVectorImpl<TemplateIdAnnotation *> &Container) + : Container(Container) {} + + ~DestroyTemplateIdAnnotationsRAIIObj() { + for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I = + Container.begin(), + E = Container.end(); + I != E; ++I) + (*I)->Destroy(); + Container.clear(); + } +}; } // end anonymous namespace IdentifierInfo *Parser::getSEHExceptKeyword() { @@ -414,6 +434,15 @@ Parser::~Parser() { PP.clearCodeCompletionHandler(); + if (getLangOpts().DelayedTemplateParsing && + !PP.isIncrementalProcessingEnabled() && !TemplateIds.empty()) { + // If an ASTConsumer parsed delay-parsed templates in their + // HandleTranslationUnit() method, TemplateIds created there were not + // guarded by a DestroyTemplateIdAnnotationsRAIIObj object in + // ParseTopLevelDecl(). Destroy them here. + DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); + } + assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?"); } @@ -434,6 +463,10 @@ void Parser::Initialize() { ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway"); ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy"); ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref"); + ObjCTypeQuals[objc_nonnull] = &PP.getIdentifierTable().get("nonnull"); + ObjCTypeQuals[objc_nullable] = &PP.getIdentifierTable().get("nullable"); + ObjCTypeQuals[objc_null_unspecified] + = &PP.getIdentifierTable().get("null_unspecified"); } Ident_instancetype = nullptr; @@ -443,11 +476,15 @@ void Parser::Initialize() { Ident_super = &PP.getIdentifierTable().get("super"); - if (getLangOpts().AltiVec) { + Ident_vector = nullptr; + Ident_bool = nullptr; + Ident_pixel = nullptr; + if (getLangOpts().AltiVec || getLangOpts().ZVector) { Ident_vector = &PP.getIdentifierTable().get("vector"); - Ident_pixel = &PP.getIdentifierTable().get("pixel"); Ident_bool = &PP.getIdentifierTable().get("bool"); } + if (getLangOpts().AltiVec) + Ident_pixel = &PP.getIdentifierTable().get("pixel"); Ident_introduced = nullptr; Ident_deprecated = nullptr; @@ -490,26 +527,6 @@ void Parser::Initialize() { ConsumeToken(); } -namespace { - /// \brief RAIIObject to destroy the contents of a SmallVector of - /// TemplateIdAnnotation pointers and clear the vector. - class DestroyTemplateIdAnnotationsRAIIObj { - SmallVectorImpl<TemplateIdAnnotation *> &Container; - public: - DestroyTemplateIdAnnotationsRAIIObj(SmallVectorImpl<TemplateIdAnnotation *> - &Container) - : Container(Container) {} - - ~DestroyTemplateIdAnnotationsRAIIObj() { - for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I = - Container.begin(), E = Container.end(); - I != E; ++I) - (*I)->Destroy(); - Container.clear(); - } - }; -} - void Parser::LateTemplateParserCleanupCallback(void *P) { // While this RAII helper doesn't bracket any actual work, the destructor will // clean up annotations that were created during ActOnEndOfTranslationUnit @@ -541,8 +558,14 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) { return false; case tok::annot_module_begin: + Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>( + Tok.getAnnotationValue())); + ConsumeToken(); + return false; + case tok::annot_module_end: - // FIXME: Update visibility based on the submodule we're in. + Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>( + Tok.getAnnotationValue())); ConsumeToken(); return false; @@ -669,8 +692,18 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, SourceLocation StartLoc = Tok.getLocation(); SourceLocation EndLoc; + ExprResult Result(ParseSimpleAsm(&EndLoc)); + // Check if GNU-style InlineAsm is disabled. + // Empty asm string is allowed because it will not introduce + // any assembly code. + if (!(getLangOpts().GNUAsm || Result.isInvalid())) { + const auto *SL = cast<StringLiteral>(Result.get()); + if (!SL->getString().trim().empty()) + Diag(StartLoc, diag::err_gnu_inline_asm_disabled); + } + ExpectAndConsume(tok::semi, diag::err_expected_after, "top-level asm block"); @@ -1048,7 +1081,6 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, if (TryConsumeToken(tok::equal)) { assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='"); - Actions.ActOnFinishFunctionBody(Res, nullptr, false); bool Delete = false; SourceLocation KWLoc; @@ -1076,6 +1108,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, SkipUntil(tok::semi); } + Stmt *GeneratedBody = Res ? Res->getBody() : nullptr; + Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false); return Res; } @@ -1383,14 +1417,35 @@ Parser::TryAnnotateName(bool IsAddressOfOperand, // It's not something we know about. Leave it unannotated. break; - case Sema::NC_Type: - Tok.setKind(tok::annot_typename); - setTypeAnnotation(Tok, Classification.getType()); - Tok.setAnnotationEndLoc(NameLoc); + case Sema::NC_Type: { + SourceLocation BeginLoc = NameLoc; if (SS.isNotEmpty()) - Tok.setLocation(SS.getBeginLoc()); + BeginLoc = SS.getBeginLoc(); + + /// An Objective-C object type followed by '<' is a specialization of + /// a parameterized class type or a protocol-qualified type. + ParsedType Ty = Classification.getType(); + if (getLangOpts().ObjC1 && NextToken().is(tok::less) && + (Ty.get()->isObjCObjectType() || + Ty.get()->isObjCObjectPointerType())) { + // Consume the name. + SourceLocation IdentifierLoc = ConsumeToken(); + SourceLocation NewEndLoc; + TypeResult NewType + = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty, + /*consumeLastToken=*/false, + NewEndLoc); + if (NewType.isUsable()) + Ty = NewType.get(); + } + + Tok.setKind(tok::annot_typename); + setTypeAnnotation(Tok, Ty); + Tok.setAnnotationEndLoc(Tok.getLocation()); + Tok.setLocation(BeginLoc); PP.AnnotateCachedTokens(Tok); return ANK_Success; + } case Sema::NC_Expression: Tok.setKind(tok::annot_primary_expr); @@ -1597,13 +1652,33 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext, // A FixIt was applied as a result of typo correction if (CorrectedII) Tok.setIdentifierInfo(CorrectedII); + + SourceLocation BeginLoc = Tok.getLocation(); + if (SS.isNotEmpty()) // it was a C++ qualified type name. + BeginLoc = SS.getBeginLoc(); + + /// An Objective-C object type followed by '<' is a specialization of + /// a parameterized class type or a protocol-qualified type. + if (getLangOpts().ObjC1 && NextToken().is(tok::less) && + (Ty.get()->isObjCObjectType() || + Ty.get()->isObjCObjectPointerType())) { + // Consume the name. + SourceLocation IdentifierLoc = ConsumeToken(); + SourceLocation NewEndLoc; + TypeResult NewType + = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty, + /*consumeLastToken=*/false, + NewEndLoc); + if (NewType.isUsable()) + Ty = NewType.get(); + } + // This is a typename. Replace the current token in-place with an // annotation type token. Tok.setKind(tok::annot_typename); setTypeAnnotation(Tok, Ty); Tok.setAnnotationEndLoc(Tok.getLocation()); - if (SS.isNotEmpty()) // it was a C++ qualified type name. - Tok.setLocation(SS.getBeginLoc()); + Tok.setLocation(BeginLoc); // In case the tokens were cached, have Preprocessor replace // them with the annotation token. |