summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse')
-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
5 files changed, 128 insertions, 0 deletions
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(),
OpenPOWER on IntegriCloud