diff options
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/FrontendActions.cpp | 72 |
2 files changed, 75 insertions, 0 deletions
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 973c5a42a5..1dd501e982 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -425,6 +425,7 @@ static const char *getActionName(frontend::ActionKind Kind) { case frontend::PrintDeclContext: return "-print-decl-contexts"; case frontend::PrintPreamble: return "-print-preamble"; case frontend::PrintPreprocessedInput: return "-E"; + case frontend::PubnamesDump: return "-pubnames-dump"; case frontend::RewriteMacros: return "-rewrite-macros"; case frontend::RewriteObjC: return "-rewrite-objc"; case frontend::RewriteTest: return "-rewrite-test"; @@ -1360,6 +1361,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::PrintPreamble; break; case OPT_E: Opts.ProgramAction = frontend::PrintPreprocessedInput; break; + case OPT_pubnames_dump: + Opts.ProgramAction = frontend::PubnamesDump; break; case OPT_rewrite_macros: Opts.ProgramAction = frontend::RewriteMacros; break; case OPT_rewrite_objc: diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 737ee4a098..b4a439d423 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" +#include <set> using namespace clang; @@ -354,6 +355,77 @@ ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, return new ASTConsumer(); } +namespace { + class PubnamesDumpConsumer : public ASTConsumer { + Preprocessor &PP; + + /// \brief Determine whether the given identifier provides a 'public' name. + bool isPublicName(IdentifierInfo *II) { + // If there are any top-level declarations associated with this + // identifier, it is a public name. + if (II->getFETokenInfo<void>()) + return true; + + // If this identifier is the name of a non-builtin macro that isn't + // defined on the command line or implicitly by the front end, it is a + // public name. + if (II->hasMacroDefinition()) { + if (MacroInfo *M = PP.getMacroInfo(II)) + if (!M->isBuiltinMacro()) { + SourceLocation Loc = M->getDefinitionLoc(); + FileID File = PP.getSourceManager().getFileID(Loc); + if (PP.getSourceManager().getFileEntryForID(File)) + return true; + } + } + + return false; + } + + public: + PubnamesDumpConsumer(Preprocessor &PP) : PP(PP) { } + + virtual void HandleTranslationUnit(ASTContext &Ctx) { + std::set<StringRef> Pubnames; + + // Add the names of any non-builtin macros. + for (IdentifierTable::iterator I = Ctx.Idents.begin(), + IEnd = Ctx.Idents.end(); + I != IEnd; ++I) { + if (isPublicName(I->second)) + Pubnames.insert(I->first()); + } + + // If there is an external identifier lookup source, consider those + // identifiers as well. + if (IdentifierInfoLookup *External + = Ctx.Idents.getExternalIdentifierLookup()) { + OwningPtr<IdentifierIterator> Iter(External->getIdentifiers()); + do { + StringRef Name = Iter->Next(); + if (Name.empty()) + break; + + if (isPublicName(PP.getIdentifierInfo(Name))) + Pubnames.insert(Name); + } while (true); + } + + // Print the names, in lexicographical order. + for (std::set<StringRef>::iterator N = Pubnames.begin(), + NEnd = Pubnames.end(); + N != NEnd; ++N) { + llvm::outs() << *N << '\n'; + } + } + }; +} + +ASTConsumer *PubnamesDumpAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + return new PubnamesDumpConsumer(CI.getPreprocessor()); +} + //===----------------------------------------------------------------------===// // Preprocessor Actions //===----------------------------------------------------------------------===// |