Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 978fc9c

Browse files
committed
Introduce a -cc1-level option -pubnames-dump, which simply dumps the
list of identifiers that that 'public' names at the end of the translation unit, e.g., defined macros or identifiers with top-level names, in sorted order. Meant to support <rdar://problem/10921596>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153522 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 2610f90 commit 978fc9c

File tree

7 files changed

+108
-0
lines changed

7 files changed

+108
-0
lines changed

include/clang/Driver/CC1Options.td

+3
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ def ast_view : Flag<"-ast-view">,
422422
HelpText<"Build ASTs and view them with GraphViz">;
423423
def print_decl_contexts : Flag<"-print-decl-contexts">,
424424
HelpText<"Print DeclContexts and their Decls">;
425+
def pubnames_dump : Flag<"-pubnames-dump">,
426+
HelpText<"Print all of the public (global) names in the source, e.g., the "
427+
"names of all global declarations and macros">;
425428
def emit_module : Flag<"-emit-module">,
426429
HelpText<"Generate pre-compiled module file from a module map">;
427430
def emit_pth : Flag<"-emit-pth">,

include/clang/Frontend/FrontendActions.h

+9
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,15 @@ class PrintPreambleAction : public FrontendAction {
173173
virtual bool usesPreprocessorOnly() const { return true; }
174174
};
175175

176+
class PubnamesDumpAction : public ASTFrontendAction {
177+
protected:
178+
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
179+
StringRef InFile);
180+
181+
public:
182+
virtual bool hasCodeCompletionSupport() const { return false; }
183+
};
184+
176185
//===----------------------------------------------------------------------===//
177186
// Preprocessor Actions
178187
//===----------------------------------------------------------------------===//

include/clang/Frontend/FrontendOptions.h

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace frontend {
4242
PrintDeclContext, ///< Print DeclContext and their Decls.
4343
PrintPreamble, ///< Print the "preamble" of the input file
4444
PrintPreprocessedInput, ///< -E mode.
45+
PubnamesDump, ///< Print all of the "public" names in the source.
4546
RewriteMacros, ///< Expand macros but not #includes.
4647
RewriteObjC, ///< ObjC->C Rewriter.
4748
RewriteTest, ///< Rewriter playground

lib/Frontend/CompilerInvocation.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ static const char *getActionName(frontend::ActionKind Kind) {
425425
case frontend::PrintDeclContext: return "-print-decl-contexts";
426426
case frontend::PrintPreamble: return "-print-preamble";
427427
case frontend::PrintPreprocessedInput: return "-E";
428+
case frontend::PubnamesDump: return "-pubnames-dump";
428429
case frontend::RewriteMacros: return "-rewrite-macros";
429430
case frontend::RewriteObjC: return "-rewrite-objc";
430431
case frontend::RewriteTest: return "-rewrite-test";
@@ -1360,6 +1361,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
13601361
Opts.ProgramAction = frontend::PrintPreamble; break;
13611362
case OPT_E:
13621363
Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
1364+
case OPT_pubnames_dump:
1365+
Opts.ProgramAction = frontend::PubnamesDump; break;
13631366
case OPT_rewrite_macros:
13641367
Opts.ProgramAction = frontend::RewriteMacros; break;
13651368
case OPT_rewrite_objc:

lib/Frontend/FrontendActions.cpp

+72
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/Support/MemoryBuffer.h"
2626
#include "llvm/Support/raw_ostream.h"
2727
#include "llvm/Support/system_error.h"
28+
#include <set>
2829

2930
using namespace clang;
3031

@@ -354,6 +355,77 @@ ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
354355
return new ASTConsumer();
355356
}
356357

358+
namespace {
359+
class PubnamesDumpConsumer : public ASTConsumer {
360+
Preprocessor &PP;
361+
362+
/// \brief Determine whether the given identifier provides a 'public' name.
363+
bool isPublicName(IdentifierInfo *II) {
364+
// If there are any top-level declarations associated with this
365+
// identifier, it is a public name.
366+
if (II->getFETokenInfo<void>())
367+
return true;
368+
369+
// If this identifier is the name of a non-builtin macro that isn't
370+
// defined on the command line or implicitly by the front end, it is a
371+
// public name.
372+
if (II->hasMacroDefinition()) {
373+
if (MacroInfo *M = PP.getMacroInfo(II))
374+
if (!M->isBuiltinMacro()) {
375+
SourceLocation Loc = M->getDefinitionLoc();
376+
FileID File = PP.getSourceManager().getFileID(Loc);
377+
if (PP.getSourceManager().getFileEntryForID(File))
378+
return true;
379+
}
380+
}
381+
382+
return false;
383+
}
384+
385+
public:
386+
PubnamesDumpConsumer(Preprocessor &PP) : PP(PP) { }
387+
388+
virtual void HandleTranslationUnit(ASTContext &Ctx) {
389+
std::set<StringRef> Pubnames;
390+
391+
// Add the names of any non-builtin macros.
392+
for (IdentifierTable::iterator I = Ctx.Idents.begin(),
393+
IEnd = Ctx.Idents.end();
394+
I != IEnd; ++I) {
395+
if (isPublicName(I->second))
396+
Pubnames.insert(I->first());
397+
}
398+
399+
// If there is an external identifier lookup source, consider those
400+
// identifiers as well.
401+
if (IdentifierInfoLookup *External
402+
= Ctx.Idents.getExternalIdentifierLookup()) {
403+
OwningPtr<IdentifierIterator> Iter(External->getIdentifiers());
404+
do {
405+
StringRef Name = Iter->Next();
406+
if (Name.empty())
407+
break;
408+
409+
if (isPublicName(PP.getIdentifierInfo(Name)))
410+
Pubnames.insert(Name);
411+
} while (true);
412+
}
413+
414+
// Print the names, in lexicographical order.
415+
for (std::set<StringRef>::iterator N = Pubnames.begin(),
416+
NEnd = Pubnames.end();
417+
N != NEnd; ++N) {
418+
llvm::outs() << *N << '\n';
419+
}
420+
}
421+
};
422+
}
423+
424+
ASTConsumer *PubnamesDumpAction::CreateASTConsumer(CompilerInstance &CI,
425+
StringRef InFile) {
426+
return new PubnamesDumpConsumer(CI.getPreprocessor());
427+
}
428+
357429
//===----------------------------------------------------------------------===//
358430
// Preprocessor Actions
359431
//===----------------------------------------------------------------------===//

lib/FrontendTool/ExecuteCompilerInvocation.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
7272
case PrintDeclContext: return new DeclContextPrintAction();
7373
case PrintPreamble: return new PrintPreambleAction();
7474
case PrintPreprocessedInput: return new PrintPreprocessedAction();
75+
case PubnamesDump: return new PubnamesDumpAction();
7576
case RewriteMacros: return new RewriteMacrosAction();
7677
case RewriteObjC: return new RewriteObjCAction();
7778
case RewriteTest: return new RewriteTestAction();

test/Misc/pubnames.c

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_cc1 -pubnames-dump %s | FileCheck %s
2+
#define FOO
3+
#define BAR
4+
#undef FOO
5+
#define WIBBLE
6+
7+
int foo();
8+
int bar(float);
9+
int wibble;
10+
11+
// CHECK: BAR
12+
// CHECK-NOT: FOO
13+
// CHECK: WIBBLE
14+
// CHECK-NOT: __clang_major__
15+
// CHECK: bar
16+
// CHECK: foo
17+
// CHECK: wibble
18+
19+

0 commit comments

Comments
 (0)