diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/MicrosoftCXXABI.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 101 | ||||
| -rw-r--r-- | clang/lib/Parse/ParsePragma.h | 7 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaAttr.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 21 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 30 |
11 files changed, 183 insertions, 19 deletions
diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp index 03d0d505514..91ffc63b770 100644 --- a/clang/lib/AST/MicrosoftCXXABI.cpp +++ b/clang/lib/AST/MicrosoftCXXABI.cpp @@ -109,14 +109,6 @@ CXXRecordDecl::getMSInheritanceModel() const { return IA->getSemanticSpelling(); } -void CXXRecordDecl::setMSInheritanceModel() { - if (hasAttr<MSInheritanceAttr>()) - return; - - addAttr(MSInheritanceAttr::CreateImplicit( - getASTContext(), calculateInheritanceModel(), getSourceRange())); -} - // Returns the number of pointer and integer slots used to represent a member // pointer in the MS C++ ABI. // diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 083d682428e..5d68453e3fb 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -2620,6 +2620,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, continue; } + if (Tok.is(tok::annot_pragma_ms_pointers_to_members)) { + HandlePragmaMSPointersToMembers(); + continue; + } + // If we see a namespace here, a close brace was missing somewhere. if (Tok.is(tok::kw_namespace)) { DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl)); diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 41562a44e96..2655996a1ff 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -180,6 +180,14 @@ void Parser::HandlePragmaOpenCLExtension() { } } +void Parser::HandlePragmaMSPointersToMembers() { + assert(Tok.is(tok::annot_pragma_ms_pointers_to_members)); + Sema::PragmaMSPointersToMembersKind RepresentationMethod = + static_cast<Sema::PragmaMSPointersToMembersKind>( + reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); + SourceLocation PragmaLoc = ConsumeToken(); // The annotation token. + Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc); +} // #pragma GCC visibility comes in two variants: @@ -799,6 +807,99 @@ PragmaOpenMPHandler::HandlePragma(Preprocessor &PP, /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true); } +/// \brief Handle '#pragma pointers_to_members' +// The grammar for this pragma is as follows: +// +// <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance' +// +// #pragma pointers_to_members '(' 'best_case' ')' +// #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')' +// #pragma pointers_to_members '(' inheritance-model ')' +void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &Tok) { + SourceLocation PointersToMembersLoc = Tok.getLocation(); + PP.Lex(Tok); + if (Tok.isNot(tok::l_paren)) { + PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen) + << "pointers_to_members"; + return; + } + PP.Lex(Tok); + const IdentifierInfo *Arg = Tok.getIdentifierInfo(); + if (!Arg) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) + << "pointers_to_members"; + return; + } + PP.Lex(Tok); + + Sema::PragmaMSPointersToMembersKind RepresentationMethod; + if (Arg->isStr("best_case")) { + RepresentationMethod = Sema::PPTMK_BestCase; + } else { + if (Arg->isStr("full_generality")) { + if (Tok.is(tok::comma)) { + PP.Lex(Tok); + + Arg = Tok.getIdentifierInfo(); + if (!Arg) { + PP.Diag(Tok.getLocation(), + diag::err_pragma_pointers_to_members_unknown_kind) + << Tok.getKind() << /*OnlyInheritanceModels*/ 0; + return; + } + PP.Lex(Tok); + } else if (Tok.is(tok::r_paren)) { + // #pragma pointers_to_members(full_generality) implicitly specifies + // virtual_inheritance. + Arg = 0; + RepresentationMethod = Sema::PPTMK_FullGeneralityVirtualInheritance; + } else { + PP.Diag(Tok.getLocation(), diag::err_expected_punc) + << "full_generality"; + return; + } + } + + if (Arg) { + if (Arg->isStr("single_inheritance")) { + RepresentationMethod = Sema::PPTMK_FullGeneralitySingleInheritance; + } else if (Arg->isStr("multiple_inheritance")) { + RepresentationMethod = Sema::PPTMK_FullGeneralityMultipleInheritance; + } else if (Arg->isStr("virtual_inheritance")) { + RepresentationMethod = Sema::PPTMK_FullGeneralityVirtualInheritance; + } else { + PP.Diag(Tok.getLocation(), + diag::err_pragma_pointers_to_members_unknown_kind) + << Arg << /*HasPointerDeclaration*/ 1; + return; + } + } + } + + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after) + << (Arg ? Arg->getName() : "full_generality"); + return; + } + + PP.Lex(Tok); + if (Tok.isNot(tok::eod)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << "pointers_to_members"; + return; + } + + Token AnnotTok; + AnnotTok.startToken(); + AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members); + AnnotTok.setLocation(PointersToMembersLoc); + AnnotTok.setAnnotationValue( + reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod))); + PP.EnterToken(AnnotTok); +} + /// \brief Handle the Microsoft \#pragma detect_mismatch extension. /// /// The syntax is: diff --git a/clang/lib/Parse/ParsePragma.h b/clang/lib/Parse/ParsePragma.h index b41450f4ead..734bc8d6349 100644 --- a/clang/lib/Parse/ParsePragma.h +++ b/clang/lib/Parse/ParsePragma.h @@ -134,6 +134,13 @@ private: Sema &Actions; }; +class PragmaMSPointersToMembers : public PragmaHandler { +public: + explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {} + virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken); +}; + } // end namespace clang #endif diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f2e4ad9f7b1..0be14f07ae8 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -345,6 +345,11 @@ Retry: ProhibitAttributes(Attrs); return ParseOpenMPDeclarativeOrExecutableDirective(); + case tok::annot_pragma_ms_pointers_to_members: + ProhibitAttributes(Attrs); + HandlePragmaMSPointersToMembers(); + return StmtEmpty(); + } // If we reached this code, the statement must end in a semicolon. @@ -820,6 +825,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() { case tok::annot_pragma_fp_contract: HandlePragmaFPContract(); break; + case tok::annot_pragma_ms_pointers_to_members: + HandlePragmaMSPointersToMembers(); + break; default: checkForPragmas = false; break; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index efa6a1bb592..a52248f2f91 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -108,6 +108,8 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) PP.AddPragmaHandler(MSCommentHandler.get()); MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(actions)); PP.AddPragmaHandler(MSDetectMismatchHandler.get()); + MSPointersToMembers.reset(new PragmaMSPointersToMembers()); + PP.AddPragmaHandler(MSPointersToMembers.get()); } CommentSemaHandler.reset(new ActionCommentHandler(actions)); @@ -483,6 +485,8 @@ Parser::~Parser() { MSCommentHandler.reset(); PP.RemovePragmaHandler(MSDetectMismatchHandler.get()); MSDetectMismatchHandler.reset(); + PP.RemovePragmaHandler(MSPointersToMembers.get()); + MSPointersToMembers.reset(); } PP.RemovePragmaHandler("STDC", FPContractHandler.get()); @@ -702,6 +706,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, case tok::annot_pragma_openmp: ParseOpenMPDeclarativeDirective(); return DeclGroupPtrTy(); + case tok::annot_pragma_ms_pointers_to_members: + HandlePragmaMSPointersToMembers(); + return DeclGroupPtrTy(); case tok::semi: // Either a C++11 empty-declaration or attribute-declaration. SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(), diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 494fe73ed3f..b2cf59b1c84 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -75,7 +75,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), CollectStats(false), CodeCompleter(CodeCompleter), CurContext(0), OriginalLexicalContext(0), - PackContext(0), MSStructPragmaOn(false), VisContext(0), + PackContext(0), MSStructPragmaOn(false), + MSPointerToMemberRepresentationMethod(PPTMK_BestCase), VisContext(0), IsBuildingRecoveryCallExpr(false), ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0), IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0), diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 499f9587447..9f0eb91d2e4 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -287,6 +287,13 @@ void Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) { Consumer.HandleDetectMismatch(Name, Value); } +void Sema::ActOnPragmaMSPointersToMembers( + PragmaMSPointersToMembersKind RepresentationMethod, + SourceLocation PragmaLoc) { + MSPointerToMemberRepresentationMethod = RepresentationMethod; + ImplicitMSInheritanceAttrLoc = PragmaLoc; +} + void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, SourceLocation PragmaLoc) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b42b502b097..17e0f38e07d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1963,7 +1963,8 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, InheritableAttr *Attr, NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(), AttrSpellingListIndex); else if (MSInheritanceAttr *IA = dyn_cast<MSInheritanceAttr>(Attr)) - NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), AttrSpellingListIndex, + NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(), + AttrSpellingListIndex, IA->getSemanticSpelling()); else if (isa<AlignedAttr>(Attr)) // AlignedAttrs are handled separately, because we need to handle all @@ -12152,7 +12153,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>()) checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record), - IA->getRange(), + IA->getRange(), IA->getBestCase(), IA->getSemanticSpelling()); } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 66591e4bf36..65fb7266dbf 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2873,7 +2873,7 @@ void Sema::CheckAlignasUnderalignment(Decl *D) { } bool Sema::checkMSInheritanceAttrOnDefinition( - CXXRecordDecl *RD, SourceRange Range, + CXXRecordDecl *RD, SourceRange Range, bool BestCase, MSInheritanceAttr::Spelling SemanticSpelling) { assert(RD->hasDefinition() && "RD has no definition!"); @@ -2886,8 +2886,13 @@ bool Sema::checkMSInheritanceAttrOnDefinition( if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance) return false; - if (RD->calculateInheritanceModel() == SemanticSpelling) - return false; + if (BestCase) { + if (RD->calculateInheritanceModel() == SemanticSpelling) + return false; + } else { + if (RD->calculateInheritanceModel() <= SemanticSpelling) + return false; + } Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) << 0 /*definition*/; @@ -3705,7 +3710,8 @@ static void handleMSInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) return; } MSInheritanceAttr *IA = S.mergeMSInheritanceAttr( - D, Attr.getRange(), Attr.getAttributeSpellingListIndex(), + D, Attr.getRange(), /*BestCase=*/true, + Attr.getAttributeSpellingListIndex(), (MSInheritanceAttr::Spelling)Attr.getSemanticSpelling()); if (IA) D->addAttr(IA); @@ -3886,7 +3892,7 @@ static void handleDLLExportAttr(Sema &S, Decl *D, const AttributeList &Attr) { } MSInheritanceAttr * -Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, +Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase, unsigned AttrSpellingListIndex, MSInheritanceAttr::Spelling SemanticSpelling) { if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) { @@ -3900,7 +3906,8 @@ Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, CXXRecordDecl *RD = cast<CXXRecordDecl>(D); if (RD->hasDefinition()) { - if (checkMSInheritanceAttrOnDefinition(RD, Range, SemanticSpelling)) { + if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase, + SemanticSpelling)) { return 0; } } else { @@ -3917,7 +3924,7 @@ Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, } return ::new (Context) - MSInheritanceAttr(Range, Context, AttrSpellingListIndex); + MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex); } /// Handles semantic checking for features that are common to all attributes, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index f9f6cee994e..606a4c09078 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -5082,7 +5082,35 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, if (!MPTy->getClass()->isDependentType()) { RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0); - MPTy->getMostRecentCXXRecordDecl()->setMSInheritanceModel(); + CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl(); + if (!RD->hasAttr<MSInheritanceAttr>()) { + MSInheritanceAttr::Spelling InheritanceModel; + + switch (MSPointerToMemberRepresentationMethod) { + case PPTMK_BestCase: + InheritanceModel = RD->calculateInheritanceModel(); + break; + case PPTMK_FullGeneralitySingleInheritance: + InheritanceModel = MSInheritanceAttr::Keyword_single_inheritance; + break; + case PPTMK_FullGeneralityMultipleInheritance: + InheritanceModel = + MSInheritanceAttr::Keyword_multiple_inheritance; + break; + case PPTMK_FullGeneralityVirtualInheritance: + InheritanceModel = + MSInheritanceAttr::Keyword_unspecified_inheritance; + break; + } + + RD->addAttr(MSInheritanceAttr::CreateImplicit( + getASTContext(), InheritanceModel, + /*BestCase=*/MSPointerToMemberRepresentationMethod == + PPTMK_BestCase, + ImplicitMSInheritanceAttrLoc.isValid() + ? ImplicitMSInheritanceAttrLoc + : RD->getSourceRange())); + } } } } |

