mirror of https://github.com/microsoft/clang.git
Parser support for #pragma clang __debug captured
This patch implements parsing ‘#pragma clang __debug’ as a first step for implementing captured statements. Captured statements are a mechanism for doing outlining in the AST. see http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-January/027540.html. Currently returns StmtEmpty Author: Andy Zhang <andy.zhang@intel.com> Differential Revision: http://llvm-reviews.chandlerc.com/D369 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179614 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f491013207
commit
85192c7fe1
|
@ -615,6 +615,11 @@ ANNOTATION(pragma_pack)
|
||||||
// handles them.
|
// handles them.
|
||||||
ANNOTATION(pragma_parser_crash)
|
ANNOTATION(pragma_parser_crash)
|
||||||
|
|
||||||
|
// Annotation for #pragma clang __debug captured...
|
||||||
|
// The lexer produces these so that they only take effect when the parser
|
||||||
|
// handles them.
|
||||||
|
ANNOTATION(pragma_captured)
|
||||||
|
|
||||||
// Annotation for #pragma ms_struct...
|
// Annotation for #pragma ms_struct...
|
||||||
// The lexer produces these so that they only take effect when the parser
|
// The lexer produces these so that they only take effect when the parser
|
||||||
// handles them.
|
// handles them.
|
||||||
|
|
|
@ -159,6 +159,12 @@ public:
|
||||||
const std::string &Str) {
|
const std::string &Str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Callback invoked when a \#pragma clang __debug directive is read.
|
||||||
|
/// \param Loc The location of the debug directive.
|
||||||
|
/// \param DebugType The identifier following __debug.
|
||||||
|
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) {
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Callback invoked when a \#pragma message directive is read.
|
/// \brief Callback invoked when a \#pragma message directive is read.
|
||||||
/// \param Loc The location of the message directive.
|
/// \param Loc The location of the message directive.
|
||||||
/// \param Str The text of the message directive.
|
/// \param Str The text of the message directive.
|
||||||
|
|
|
@ -422,6 +422,10 @@ private:
|
||||||
/// #pragma OPENCL EXTENSION...
|
/// #pragma OPENCL EXTENSION...
|
||||||
void HandlePragmaOpenCLExtension();
|
void HandlePragmaOpenCLExtension();
|
||||||
|
|
||||||
|
/// \brief Handle the annotation token produced for
|
||||||
|
/// #pragma clang __debug captured
|
||||||
|
StmtResult HandlePragmaCaptured();
|
||||||
|
|
||||||
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
|
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
|
||||||
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
|
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
|
||||||
/// returns the token after Tok, etc.
|
/// returns the token after Tok, etc.
|
||||||
|
|
|
@ -140,6 +140,7 @@ public:
|
||||||
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
|
virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
|
||||||
const std::string &Str);
|
const std::string &Str);
|
||||||
virtual void PragmaMessage(SourceLocation Loc, StringRef Str);
|
virtual void PragmaMessage(SourceLocation Loc, StringRef Str);
|
||||||
|
virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType);
|
||||||
virtual void PragmaDiagnosticPush(SourceLocation Loc,
|
virtual void PragmaDiagnosticPush(SourceLocation Loc,
|
||||||
StringRef Namespace);
|
StringRef Namespace);
|
||||||
virtual void PragmaDiagnosticPop(SourceLocation Loc,
|
virtual void PragmaDiagnosticPop(SourceLocation Loc,
|
||||||
|
@ -419,6 +420,17 @@ void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
|
||||||
setEmittedDirectiveOnThisLine();
|
setEmittedDirectiveOnThisLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintPPOutputPPCallbacks::PragmaDebug(SourceLocation Loc,
|
||||||
|
StringRef DebugType) {
|
||||||
|
startNewLineIfNeeded();
|
||||||
|
MoveToLine(Loc);
|
||||||
|
|
||||||
|
OS << "#pragma clang __debug ";
|
||||||
|
OS << DebugType;
|
||||||
|
|
||||||
|
setEmittedDirectiveOnThisLine();
|
||||||
|
}
|
||||||
|
|
||||||
void PrintPPOutputPPCallbacks::
|
void PrintPPOutputPPCallbacks::
|
||||||
PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
|
PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) {
|
||||||
startNewLineIfNeeded();
|
startNewLineIfNeeded();
|
||||||
|
|
|
@ -995,10 +995,40 @@ struct PragmaDebugHandler : public PragmaHandler {
|
||||||
llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
|
llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
|
||||||
if (CRC)
|
if (CRC)
|
||||||
CRC->HandleCrash();
|
CRC->HandleCrash();
|
||||||
|
} else if (II->isStr("captured")) {
|
||||||
|
HandleCaptured(PP);
|
||||||
} else {
|
} else {
|
||||||
PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
|
PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
|
||||||
<< II->getName();
|
<< II->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PPCallbacks *Callbacks = PP.getPPCallbacks();
|
||||||
|
if (Callbacks)
|
||||||
|
Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleCaptured(Preprocessor &PP) {
|
||||||
|
// Skip if emitting preprocessed output.
|
||||||
|
if (PP.isPreprocessedOutput())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Token Tok;
|
||||||
|
PP.LexUnexpandedToken(Tok);
|
||||||
|
|
||||||
|
if (Tok.isNot(tok::eod)) {
|
||||||
|
PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
|
||||||
|
<< "pragma clang __debug captured";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceLocation NameLoc = Tok.getLocation();
|
||||||
|
Token *Toks = PP.getPreprocessorAllocator().Allocate<Token>(1);
|
||||||
|
Toks->startToken();
|
||||||
|
Toks->setKind(tok::annot_pragma_captured);
|
||||||
|
Toks->setLocation(NameLoc);
|
||||||
|
|
||||||
|
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
|
||||||
|
/*OwnsTokens=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable MSVC warning about runtime stack overflow.
|
// Disable MSVC warning about runtime stack overflow.
|
||||||
|
|
|
@ -122,6 +122,19 @@ void Parser::HandlePragmaFPContract() {
|
||||||
ConsumeToken(); // The annotation token.
|
ConsumeToken(); // The annotation token.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StmtResult Parser::HandlePragmaCaptured()
|
||||||
|
{
|
||||||
|
assert(Tok.is(tok::annot_pragma_captured));
|
||||||
|
ConsumeToken();
|
||||||
|
|
||||||
|
if (Tok.isNot(tok::l_brace)) {
|
||||||
|
PP.Diag(Tok, diag::err_expected_lbrace);
|
||||||
|
return StmtError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return StmtEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
|
typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +164,8 @@ void Parser::HandlePragmaOpenCLExtension() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma GCC visibility comes in two variants:
|
// #pragma GCC visibility comes in two variants:
|
||||||
// 'push' '(' [visibility] ')'
|
// 'push' '(' [visibility] ')'
|
||||||
// 'pop'
|
// 'pop'
|
||||||
|
|
|
@ -289,6 +289,9 @@ Retry:
|
||||||
HandlePragmaOpenCLExtension();
|
HandlePragmaOpenCLExtension();
|
||||||
return StmtEmpty();
|
return StmtEmpty();
|
||||||
|
|
||||||
|
case tok::annot_pragma_captured:
|
||||||
|
return HandlePragmaCaptured();
|
||||||
|
|
||||||
case tok::annot_pragma_openmp:
|
case tok::annot_pragma_openmp:
|
||||||
SourceLocation DeclStart = Tok.getLocation();
|
SourceLocation DeclStart = Tok.getLocation();
|
||||||
DeclGroupPtrTy Res = ParseOpenMPDeclarativeDirective();
|
DeclGroupPtrTy Res = ParseOpenMPDeclarativeDirective();
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// RUN: %clang_cc1 -verify %s
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
#pragma clang __debug captured x // expected-warning {{extra tokens at end of #pragma clang __debug captured directive}}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
#pragma clang __debug captured
|
||||||
|
int x; // expected-error {{expected '{'}}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// RUN: %clang_cc1 -E %s | FileCheck %s
|
||||||
|
|
||||||
|
// Test pragma clang __debug captured, for Captured Statements
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
#pragma clang __debug captured
|
||||||
|
{
|
||||||
|
}
|
||||||
|
// CHECK: void test1()
|
||||||
|
// CHECK: {
|
||||||
|
// CHECK: #pragma clang __debug captured
|
||||||
|
}
|
Loading…
Reference in New Issue