summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/MicrosoftCXXABI.cpp8
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp5
-rw-r--r--clang/lib/Parse/ParsePragma.cpp101
-rw-r--r--clang/lib/Parse/ParsePragma.h7
-rw-r--r--clang/lib/Parse/ParseStmt.cpp8
-rw-r--r--clang/lib/Parse/Parser.cpp7
-rw-r--r--clang/lib/Sema/Sema.cpp3
-rw-r--r--clang/lib/Sema/SemaAttr.cpp7
-rw-r--r--clang/lib/Sema/SemaDecl.cpp5
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp21
-rw-r--r--clang/lib/Sema/SemaType.cpp30
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()));
+ }
}
}
}
OpenPOWER on IntegriCloud