Endill created this revision. Endill added reviewers: clang-language-wg, aaron.ballman. Herald added a project: All. Endill requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Extend `#pragma clang __debug dump` to support not only single identifier, but an expression as well. This makes it possible to test ADL and overload resolution directly, without being creative to make them observable via diagnostics (e.g. when over.match.best <http://eel.is/c++draft/over.match.best> is involved). This implementation has a known limitation of not supporting dependent expressions properly, but it's quite useful even without such support. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D144115 Files: clang/lib/Lex/Pragma.cpp clang/lib/Parse/ParsePragma.cpp Index: clang/lib/Parse/ParsePragma.cpp =================================================================== --- clang/lib/Parse/ParsePragma.cpp +++ clang/lib/Parse/ParsePragma.cpp @@ -13,6 +13,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/Token.h" #include "clang/Parse/LoopHint.h" @@ -706,10 +707,27 @@ void Parser::HandlePragmaDump() { assert(Tok.is(tok::annot_pragma_dump)); - IdentifierInfo *II = - reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue()); - Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II); ConsumeAnnotationToken(); + if (Tok.is(tok::eod)) { + PP.Diag(Tok, diag::warn_pragma_debug_missing_argument) << "dump"; + } else if (NextToken().is(tok::eod)) { + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok, diag::warn_pragma_debug_unexpected_argument); + ConsumeAnyToken(); + ExpectAndConsume(tok::eod); + return; + } + IdentifierInfo *II = Tok.getIdentifierInfo(); + Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II); + ConsumeToken(); + } else { + ExprResult E = ParseExpression(); + if (!E.isInvalid()) { + E.get()->dump(); + } + SkipUntil(tok::eod, StopBeforeMatch); + } + ExpectAndConsume(tok::eod); } void Parser::HandlePragmaWeak() { Index: clang/lib/Lex/Pragma.cpp =================================================================== --- clang/lib/Lex/Pragma.cpp +++ clang/lib/Lex/Pragma.cpp @@ -1066,21 +1066,11 @@ PP.EnterToken(Crasher, /*IsReinject*/ false); } } else if (II->isStr("dump")) { - Token Identifier; - PP.LexUnexpandedToken(Identifier); - if (auto *DumpII = Identifier.getIdentifierInfo()) { - Token DumpAnnot; - DumpAnnot.startToken(); - DumpAnnot.setKind(tok::annot_pragma_dump); - DumpAnnot.setAnnotationRange( - SourceRange(Tok.getLocation(), Identifier.getLocation())); - DumpAnnot.setAnnotationValue(DumpII); - PP.DiscardUntilEndOfDirective(); - PP.EnterToken(DumpAnnot, /*IsReinject*/false); - } else { - PP.Diag(Identifier, diag::warn_pragma_debug_missing_argument) - << II->getName(); - } + Token DumpAnnot; + DumpAnnot.startToken(); + DumpAnnot.setKind(tok::annot_pragma_dump); + DumpAnnot.setAnnotationRange(SourceRange(Tok.getLocation())); + PP.EnterToken(DumpAnnot, /*IsReinject*/false); } else if (II->isStr("diag_mapping")) { Token DiagName; PP.LexUnexpandedToken(DiagName);
Index: clang/lib/Parse/ParsePragma.cpp =================================================================== --- clang/lib/Parse/ParsePragma.cpp +++ clang/lib/Parse/ParsePragma.cpp @@ -13,6 +13,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Lex/LexDiagnostic.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/Token.h" #include "clang/Parse/LoopHint.h" @@ -706,10 +707,27 @@ void Parser::HandlePragmaDump() { assert(Tok.is(tok::annot_pragma_dump)); - IdentifierInfo *II = - reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue()); - Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II); ConsumeAnnotationToken(); + if (Tok.is(tok::eod)) { + PP.Diag(Tok, diag::warn_pragma_debug_missing_argument) << "dump"; + } else if (NextToken().is(tok::eod)) { + if (Tok.isNot(tok::identifier)) { + PP.Diag(Tok, diag::warn_pragma_debug_unexpected_argument); + ConsumeAnyToken(); + ExpectAndConsume(tok::eod); + return; + } + IdentifierInfo *II = Tok.getIdentifierInfo(); + Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II); + ConsumeToken(); + } else { + ExprResult E = ParseExpression(); + if (!E.isInvalid()) { + E.get()->dump(); + } + SkipUntil(tok::eod, StopBeforeMatch); + } + ExpectAndConsume(tok::eod); } void Parser::HandlePragmaWeak() { Index: clang/lib/Lex/Pragma.cpp =================================================================== --- clang/lib/Lex/Pragma.cpp +++ clang/lib/Lex/Pragma.cpp @@ -1066,21 +1066,11 @@ PP.EnterToken(Crasher, /*IsReinject*/ false); } } else if (II->isStr("dump")) { - Token Identifier; - PP.LexUnexpandedToken(Identifier); - if (auto *DumpII = Identifier.getIdentifierInfo()) { - Token DumpAnnot; - DumpAnnot.startToken(); - DumpAnnot.setKind(tok::annot_pragma_dump); - DumpAnnot.setAnnotationRange( - SourceRange(Tok.getLocation(), Identifier.getLocation())); - DumpAnnot.setAnnotationValue(DumpII); - PP.DiscardUntilEndOfDirective(); - PP.EnterToken(DumpAnnot, /*IsReinject*/false); - } else { - PP.Diag(Identifier, diag::warn_pragma_debug_missing_argument) - << II->getName(); - } + Token DumpAnnot; + DumpAnnot.startToken(); + DumpAnnot.setKind(tok::annot_pragma_dump); + DumpAnnot.setAnnotationRange(SourceRange(Tok.getLocation())); + PP.EnterToken(DumpAnnot, /*IsReinject*/false); } else if (II->isStr("diag_mapping")) { Token DiagName; PP.LexUnexpandedToken(DiagName);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits