|
25 | 25 | #include "llvm/Support/MemoryBuffer.h"
|
26 | 26 | #include "llvm/Support/raw_ostream.h"
|
27 | 27 | #include "llvm/Support/system_error.h"
|
| 28 | +#include <set> |
28 | 29 |
|
29 | 30 | using namespace clang;
|
30 | 31 |
|
@@ -354,6 +355,77 @@ ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
|
354 | 355 | return new ASTConsumer();
|
355 | 356 | }
|
356 | 357 |
|
| 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 | + |
357 | 429 | //===----------------------------------------------------------------------===//
|
358 | 430 | // Preprocessor Actions
|
359 | 431 | //===----------------------------------------------------------------------===//
|
|
0 commit comments