mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-16 05:10:32 +00:00
Improve AST dumping:
1) When dumping a declaration that declares a name for a type, also dump the named type. 2) Add a #pragma clang __debug dump X, that dumps the lookup results for X in the current context. llvm-svn: 257529
This commit is contained in:
parent
c81c8c66d5
commit
ba3a4f917f
@ -490,6 +490,8 @@ def warn_pragma_diagnostic_unknown_warning :
|
|||||||
// - #pragma __debug
|
// - #pragma __debug
|
||||||
def warn_pragma_debug_unexpected_command : Warning<
|
def warn_pragma_debug_unexpected_command : Warning<
|
||||||
"unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
|
"unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
|
||||||
|
def warn_pragma_debug_missing_argument : Warning<
|
||||||
|
"missing argument to debug command '%0'">, InGroup<IgnoredPragmas>;
|
||||||
|
|
||||||
def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
|
def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
|
||||||
def err_paste_at_start : Error<
|
def err_paste_at_start : Error<
|
||||||
|
@ -699,6 +699,11 @@ ANNOTATION(pragma_parser_crash)
|
|||||||
// handles them.
|
// handles them.
|
||||||
ANNOTATION(pragma_captured)
|
ANNOTATION(pragma_captured)
|
||||||
|
|
||||||
|
// Annotation for #pragma clang __debug dump...
|
||||||
|
// The lexer produces these so that the parser and semantic analysis can
|
||||||
|
// look up and dump the operand.
|
||||||
|
ANNOTATION(pragma_dump)
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -501,6 +501,10 @@ private:
|
|||||||
/// #pragma align...
|
/// #pragma align...
|
||||||
void HandlePragmaAlign();
|
void HandlePragmaAlign();
|
||||||
|
|
||||||
|
/// \brief Handle the annotation token produced for
|
||||||
|
/// #pragma clang __debug dump...
|
||||||
|
void HandlePragmaDump();
|
||||||
|
|
||||||
/// \brief Handle the annotation token produced for
|
/// \brief Handle the annotation token produced for
|
||||||
/// #pragma weak id...
|
/// #pragma weak id...
|
||||||
void HandlePragmaWeak();
|
void HandlePragmaWeak();
|
||||||
|
@ -515,6 +515,7 @@ public:
|
|||||||
configure();
|
configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dump();
|
||||||
void print(raw_ostream &);
|
void print(raw_ostream &);
|
||||||
|
|
||||||
/// Suppress the diagnostics that would normally fire because of this
|
/// Suppress the diagnostics that would normally fire because of this
|
||||||
|
@ -7629,6 +7629,9 @@ public:
|
|||||||
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
|
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
|
||||||
StringLiteral *SegmentName);
|
StringLiteral *SegmentName);
|
||||||
|
|
||||||
|
/// \brief Called on #pragma clang __debug dump II
|
||||||
|
void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II);
|
||||||
|
|
||||||
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
|
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
|
||||||
void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
|
void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
|
||||||
|
|
||||||
|
@ -1055,6 +1055,7 @@ void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
|
|||||||
dumpType(D->getUnderlyingType());
|
dumpType(D->getUnderlyingType());
|
||||||
if (D->isModulePrivate())
|
if (D->isModulePrivate())
|
||||||
OS << " __module_private__";
|
OS << " __module_private__";
|
||||||
|
dumpTypeAsChild(D->getUnderlyingType());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
|
void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
|
||||||
@ -1226,6 +1227,7 @@ void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
|
|||||||
void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
|
void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
|
||||||
dumpName(D);
|
dumpName(D);
|
||||||
dumpType(D->getUnderlyingType());
|
dumpType(D->getUnderlyingType());
|
||||||
|
dumpTypeAsChild(D->getUnderlyingType());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
|
void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
|
||||||
@ -1419,6 +1421,8 @@ void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D)
|
|||||||
void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
|
void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
|
||||||
OS << ' ';
|
OS << ' ';
|
||||||
dumpBareDeclRef(D->getTargetDecl());
|
dumpBareDeclRef(D->getTargetDecl());
|
||||||
|
if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
|
||||||
|
dumpTypeAsChild(TD->getTypeForDecl());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
|
void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
|
||||||
|
@ -876,6 +876,22 @@ struct PragmaDebugHandler : public PragmaHandler {
|
|||||||
Crasher.setKind(tok::annot_pragma_parser_crash);
|
Crasher.setKind(tok::annot_pragma_parser_crash);
|
||||||
Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));
|
Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));
|
||||||
PP.EnterToken(Crasher);
|
PP.EnterToken(Crasher);
|
||||||
|
} 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);
|
||||||
|
} else {
|
||||||
|
PP.Diag(Identifier, diag::warn_pragma_debug_missing_argument)
|
||||||
|
<< II->getName();
|
||||||
|
}
|
||||||
} else if (II->isStr("llvm_fatal_error")) {
|
} else if (II->isStr("llvm_fatal_error")) {
|
||||||
llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
|
llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
|
||||||
} else if (II->isStr("llvm_unreachable")) {
|
} else if (II->isStr("llvm_unreachable")) {
|
||||||
@ -887,7 +903,8 @@ struct PragmaDebugHandler : public PragmaHandler {
|
|||||||
if (MacroII)
|
if (MacroII)
|
||||||
PP.dumpMacroInfo(MacroII);
|
PP.dumpMacroInfo(MacroII);
|
||||||
else
|
else
|
||||||
PP.Diag(MacroName, diag::warn_pragma_diagnostic_invalid);
|
PP.Diag(MacroName, diag::warn_pragma_debug_missing_argument)
|
||||||
|
<< II->getName();
|
||||||
} else if (II->isStr("overflow_stack")) {
|
} else if (II->isStr("overflow_stack")) {
|
||||||
DebugOverflowStack();
|
DebugOverflowStack();
|
||||||
} else if (II->isStr("handle_crash")) {
|
} else if (II->isStr("handle_crash")) {
|
||||||
|
@ -377,6 +377,14 @@ void Parser::HandlePragmaAlign() {
|
|||||||
Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
|
Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::HandlePragmaDump() {
|
||||||
|
assert(Tok.is(tok::annot_pragma_dump));
|
||||||
|
IdentifierInfo *II =
|
||||||
|
reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
|
||||||
|
Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
|
||||||
|
ConsumeToken();
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::HandlePragmaWeak() {
|
void Parser::HandlePragmaWeak() {
|
||||||
assert(Tok.is(tok::annot_pragma_weak));
|
assert(Tok.is(tok::annot_pragma_weak));
|
||||||
SourceLocation PragmaLoc = ConsumeToken();
|
SourceLocation PragmaLoc = ConsumeToken();
|
||||||
|
@ -366,6 +366,10 @@ Retry:
|
|||||||
case tok::annot_pragma_loop_hint:
|
case tok::annot_pragma_loop_hint:
|
||||||
ProhibitAttributes(Attrs);
|
ProhibitAttributes(Attrs);
|
||||||
return ParsePragmaLoopHint(Stmts, OnlyStatement, TrailingElseLoc, Attrs);
|
return ParsePragmaLoopHint(Stmts, OnlyStatement, TrailingElseLoc, Attrs);
|
||||||
|
|
||||||
|
case tok::annot_pragma_dump:
|
||||||
|
HandlePragmaDump();
|
||||||
|
return StmtEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we reached this code, the statement must end in a semicolon.
|
// If we reached this code, the statement must end in a semicolon.
|
||||||
@ -893,6 +897,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() {
|
|||||||
case tok::annot_pragma_ms_vtordisp:
|
case tok::annot_pragma_ms_vtordisp:
|
||||||
HandlePragmaMSVtorDisp();
|
HandlePragmaMSVtorDisp();
|
||||||
break;
|
break;
|
||||||
|
case tok::annot_pragma_dump:
|
||||||
|
HandlePragmaDump();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
checkForPragmas = false;
|
checkForPragmas = false;
|
||||||
break;
|
break;
|
||||||
|
@ -668,6 +668,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
|||||||
case tok::annot_pragma_ms_pragma:
|
case tok::annot_pragma_ms_pragma:
|
||||||
HandlePragmaMSPragma();
|
HandlePragmaMSPragma();
|
||||||
return DeclGroupPtrTy();
|
return DeclGroupPtrTy();
|
||||||
|
case tok::annot_pragma_dump:
|
||||||
|
HandlePragmaDump();
|
||||||
|
return DeclGroupPtrTy();
|
||||||
case tok::semi:
|
case tok::semi:
|
||||||
// Either a C++11 empty-declaration or attribute-declaration.
|
// Either a C++11 empty-declaration or attribute-declaration.
|
||||||
SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
|
SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
|
||||||
|
@ -650,6 +650,13 @@ void LookupResult::print(raw_ostream &Out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLVM_DUMP_METHOD void LookupResult::dump() {
|
||||||
|
llvm::errs() << "lookup results for " << getLookupName().getAsString()
|
||||||
|
<< ":\n";
|
||||||
|
for (NamedDecl *D : *this)
|
||||||
|
D->dump();
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Lookup a builtin function, when name lookup would otherwise
|
/// \brief Lookup a builtin function, when name lookup would otherwise
|
||||||
/// fail.
|
/// fail.
|
||||||
static bool LookupBuiltin(Sema &S, LookupResult &R) {
|
static bool LookupBuiltin(Sema &S, LookupResult &R) {
|
||||||
@ -4991,3 +4998,12 @@ const Sema::TypoExprState &Sema::getTypoExprState(TypoExpr *TE) const {
|
|||||||
void Sema::clearDelayedTypo(TypoExpr *TE) {
|
void Sema::clearDelayedTypo(TypoExpr *TE) {
|
||||||
DelayedTypos.erase(TE);
|
DelayedTypos.erase(TE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sema::ActOnPragmaDump(Scope *S, SourceLocation IILoc, IdentifierInfo *II) {
|
||||||
|
DeclarationNameInfo Name(II, IILoc);
|
||||||
|
LookupResult R(*this, Name, LookupAnyName, Sema::NotForRedeclaration);
|
||||||
|
R.suppressDiagnostics();
|
||||||
|
R.setHideTags(false);
|
||||||
|
LookupName(R, S);
|
||||||
|
R.dump();
|
||||||
|
}
|
||||||
|
@ -1,16 +1,31 @@
|
|||||||
// RUN: %clang_cc1 -std=c++11 -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix DECLS %s
|
// RUN: %clang_cc1 -std=c++11 -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix DECLS %s
|
||||||
// RUN: %clang_cc1 -std=c++11 -ast-dump-lookups -ast-dump-filter Test %s | FileCheck -check-prefix LOOKUPS %s
|
// RUN: %clang_cc1 -std=c++11 -ast-dump-lookups -ast-dump-filter Test %s | FileCheck -check-prefix LOOKUPS %s
|
||||||
// RUN: %clang_cc1 -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter Test %s | FileCheck -check-prefix DECLS-LOOKUPS %s
|
// RUN: %clang_cc1 -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter Test %s | FileCheck -check-prefix DECLS-LOOKUPS %s
|
||||||
|
// RUN: %clang_cc1 -std=c++11 -DPRAGMA -fsyntax-only %s 2>&1 | FileCheck -check-prefix PRAGMA %s
|
||||||
|
|
||||||
namespace Test {
|
namespace Test {
|
||||||
|
typedef int T;
|
||||||
extern int a;
|
extern int a;
|
||||||
int a = 0;
|
int a = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PRAGMA
|
||||||
|
#pragma clang __debug dump Test
|
||||||
|
// PRAGMA: lookup results for Test:
|
||||||
|
// PRAGMA-NEXT: NamespaceDecl {{.*}} Test
|
||||||
|
// PRAGMA-NEXT: |-TypedefDecl {{.*}} T 'int'
|
||||||
|
// PRAGMA-NEXT: | `-BuiltinType {{.*}} 'int'
|
||||||
|
// PRAGMA-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern
|
||||||
|
// PRAGMA-NEXT: `-VarDecl {{.*}} prev [[EXTERN_A]] {{.*}} a 'int' cinit
|
||||||
|
// PRAGMA-NEXT: `-IntegerLiteral {{.*}} 'int' 0
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Test { }
|
namespace Test { }
|
||||||
|
|
||||||
// DECLS: Dumping Test:
|
// DECLS: Dumping Test:
|
||||||
// DECLS-NEXT: NamespaceDecl {{.*}} Test
|
// DECLS-NEXT: NamespaceDecl {{.*}} Test
|
||||||
|
// DECLS-NEXT: |-TypedefDecl {{.*}} T 'int'
|
||||||
|
// DECLS-NEXT: | `-BuiltinType {{.*}} 'int'
|
||||||
// DECLS-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern
|
// DECLS-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern
|
||||||
// DECLS-NEXT: `-VarDecl {{.*}} prev [[EXTERN_A]] {{.*}} a 'int' cinit
|
// DECLS-NEXT: `-VarDecl {{.*}} prev [[EXTERN_A]] {{.*}} a 'int' cinit
|
||||||
// DECLS-NEXT: `-IntegerLiteral {{.*}} 'int' 0
|
// DECLS-NEXT: `-IntegerLiteral {{.*}} 'int' 0
|
||||||
@ -20,7 +35,7 @@ namespace Test { }
|
|||||||
|
|
||||||
// LOOKUPS: Dumping Test:
|
// LOOKUPS: Dumping Test:
|
||||||
// LOOKUPS-NEXT: StoredDeclsMap Namespace {{.*}} 'Test'
|
// LOOKUPS-NEXT: StoredDeclsMap Namespace {{.*}} 'Test'
|
||||||
// LOOKUPS-NEXT: `-DeclarationName 'a'
|
// LOOKUPS: DeclarationName 'a'
|
||||||
// LOOKUPS-NEXT: `-Var {{.*}} 'a' 'int'
|
// LOOKUPS-NEXT: `-Var {{.*}} 'a' 'int'
|
||||||
//
|
//
|
||||||
// LOOKUPS: Dumping Test:
|
// LOOKUPS: Dumping Test:
|
||||||
@ -28,7 +43,7 @@ namespace Test { }
|
|||||||
|
|
||||||
// DECLS-LOOKUPS: Dumping Test:
|
// DECLS-LOOKUPS: Dumping Test:
|
||||||
// DECLS-LOOKUPS-NEXT: StoredDeclsMap Namespace {{.*}} 'Test'
|
// DECLS-LOOKUPS-NEXT: StoredDeclsMap Namespace {{.*}} 'Test'
|
||||||
// DECLS-LOOKUPS-NEXT: `-DeclarationName 'a'
|
// DECLS-LOOKUPS: -DeclarationName 'a'
|
||||||
// DECLS-LOOKUPS-NEXT: `-Var [[A:[^ ]*]] 'a' 'int'
|
// DECLS-LOOKUPS-NEXT: `-Var [[A:[^ ]*]] 'a' 'int'
|
||||||
// DECLS-LOOKUPS-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern
|
// DECLS-LOOKUPS-NEXT: |-VarDecl [[EXTERN_A:0x[^ ]*]] {{.*}} a 'int' extern
|
||||||
// DECLS-LOOKUPS-NEXT: `-VarDecl [[A]] prev [[EXTERN_A]] {{.*}} a 'int' cinit
|
// DECLS-LOOKUPS-NEXT: `-VarDecl [[A]] prev [[EXTERN_A]] {{.*}} a 'int' cinit
|
||||||
|
Loading…
x
Reference in New Issue
Block a user