[cfe-commits] r130990 - in /cfe/trunk: include/clang-c/Index.h include/clang/Frontend/ASTUnit.h include/clang/Frontend/PreprocessorOptions.h include/clang/Lex/PreprocessingRecord.h include/clang/Lex/Preprocessor.h lib/Frontend/ASTUnit.cpp lib/Frontend/CompilerInstance.cpp lib/Lex/PreprocessingRecord.cpp lib/Lex/Preprocessor.cpp lib/Serialization/ASTReader.cpp test/Index/nested-macro-instantiations.cpp tools/c-index-test/c-index-test.c tools/libclang/CIndex.cpp

Douglas Gregor dgregor at apple.com
Fri May 6 09:33:08 PDT 2011


Author: dgregor
Date: Fri May  6 11:33:08 2011
New Revision: 130990

URL: http://llvm.org/viewvc/llvm-project?rev=130990&view=rev
Log:
Introduce a new libclang parsing flag,
CXTranslationUnit_NestedMacroInstantiations, which indicates whether
we want to see "nested" macro instantiations (e.g., those that occur
inside other macro instantiations) within the detailed preprocessing
record. Many clients (e.g., those that only care about visible tokens)
don't care about this information, and in code that uses preprocessor
metaprogramming, this information can have a very high cost.

Addresses <rdar://problem/9389320>.

Added:
    cfe/trunk/test/Index/nested-macro-instantiations.cpp
Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
    cfe/trunk/include/clang/Lex/PreprocessingRecord.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Lex/PreprocessingRecord.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Fri May  6 11:33:08 2011
@@ -829,7 +829,18 @@
    * Note: this is a *temporary* option that is available only while
    * we are testing C++ precompiled preamble support.
    */
-  CXTranslationUnit_CXXChainedPCH = 0x20
+  CXTranslationUnit_CXXChainedPCH = 0x20,
+  
+  /**
+   * \brief Used to indicate that the "detailed" preprocessing record,
+   * if requested, should also contain nested macro instantiations.
+   *
+   * Nested macro instantiations (i.e., macro instantiations that occur
+   * inside another macro instantiation) can, in some code bases, require
+   * a large amount of storage to due preprocessor metaprogramming. Moreover,
+   * its fairly rare that this information is useful for libclang clients.
+   */
+  CXTranslationUnit_NestedMacroInstantiations = 0x40
 };
 
 /**

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Fri May  6 11:33:08 2011
@@ -249,6 +249,10 @@
   /// \brief Whether we should be caching code-completion results.
   bool ShouldCacheCodeCompletionResults;
   
+  /// \brief Whether we want to include nested macro instantiations in the
+  /// detailed preprocessing record.
+  bool NestedMacroInstantiations;
+  
   static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags,
                              const char **ArgBegin, const char **ArgEnd,
                              ASTUnit &AST, bool CaptureDiagnostics);
@@ -607,7 +611,8 @@
                                              bool CaptureDiagnostics = false,
                                              bool PrecompilePreamble = false,
                                           bool CompleteTranslationUnit = true,
-                                       bool CacheCodeCompletionResults = false);
+                                       bool CacheCodeCompletionResults = false,
+                                       bool NestedMacroInstantiations = true);
 
   /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
   /// arguments, which must specify exactly one source file.
@@ -636,7 +641,8 @@
                                       bool CompleteTranslationUnit = true,
                                       bool CacheCodeCompletionResults = false,
                                       bool CXXPrecompilePreamble = false,
-                                      bool CXXChainedPCH = false);
+                                      bool CXXChainedPCH = false,
+                                      bool NestedMacroInstantiations = true);
   
   /// \brief Reparse the source files using the same command-line options that
   /// were originally used to produce this translation unit.

Modified: cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PreprocessorOptions.h?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PreprocessorOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/PreprocessorOptions.h Fri May  6 11:33:08 2011
@@ -41,6 +41,10 @@
                                /// record of all macro definitions and
                                /// instantiations.
   
+  /// \brief Whether the detailed preprocessing record includes nested macro 
+  /// instantiations.
+  unsigned DetailedRecordIncludesNestedMacroInstantiations : 1;
+  
   /// The implicit PCH included at the start of the translation unit, or empty.
   std::string ImplicitPCHInclude;
 
@@ -136,6 +140,7 @@
   
 public:
   PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
+                          DetailedRecordIncludesNestedMacroInstantiations(true),
                           DisablePCHValidation(false), DisableStatCache(false),
                           DumpDeserializedPCHDecls(false),
                           PrecompiledPreambleBytes(0, true),

Modified: cfe/trunk/include/clang/Lex/PreprocessingRecord.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessingRecord.h?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PreprocessingRecord.h (original)
+++ cfe/trunk/include/clang/Lex/PreprocessingRecord.h Fri May  6 11:33:08 2011
@@ -258,6 +258,10 @@
   /// including the various preprocessing directives processed, macros 
   /// instantiated, etc.
   class PreprocessingRecord : public PPCallbacks {
+    /// \brief Whether we should include nested macro instantiations in
+    /// the preprocessing record.
+    bool IncludeNestedMacroInstantiations;
+    
     /// \brief Allocator used to store preprocessing objects.
     llvm::BumpPtrAllocator BumpAlloc;
 
@@ -281,7 +285,8 @@
     void MaybeLoadPreallocatedEntities() const ;
     
   public:
-    PreprocessingRecord();
+    /// \brief Construct 
+    explicit PreprocessingRecord(bool IncludeNestedMacroInstantiations);
     
     /// \brief Allocate memory in the preprocessing record.
     void *Allocate(unsigned Size, unsigned Align = 8) {

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri May  6 11:33:08 2011
@@ -441,7 +441,7 @@
   
   /// \brief Create a new preprocessing record, which will keep track of 
   /// all macro expansions, macro definitions, etc.
-  void createPreprocessingRecord();
+  void createPreprocessingRecord(bool IncludeNestedMacroInstantiations);
   
   /// EnterMainSourceFile - Enter the specified FileID as the main source file,
   /// which implicitly adds the builtin defines etc.

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Fri May  6 11:33:08 2011
@@ -102,6 +102,7 @@
     ConcurrencyCheckValue(CheckUnlocked), 
     PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0),
     ShouldCacheCodeCompletionResults(false),
+    NestedMacroInstantiations(true),
     CompletionCacheTopLevelHashValue(0),
     PreambleTopLevelHashValue(0),
     CurrentTopLevelHashValue(0),
@@ -927,6 +928,8 @@
   // If the main file has been overridden due to the use of a preamble,
   // make that override happen and introduce the preamble.
   PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts();
+  PreprocessorOpts.DetailedRecordIncludesNestedMacroInstantiations
+    = NestedMacroInstantiations;
   std::string PriorImplicitPCHInclude;
   if (OverrideMainBuffer) {
     PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
@@ -1712,7 +1715,8 @@
                                              bool CaptureDiagnostics,
                                              bool PrecompilePreamble,
                                              bool CompleteTranslationUnit,
-                                             bool CacheCodeCompletionResults) {  
+                                             bool CacheCodeCompletionResults,
+                                             bool NestedMacroInstantiations) {  
   // Create the AST unit.
   llvm::OwningPtr<ASTUnit> AST;
   AST.reset(new ASTUnit(false));
@@ -1723,6 +1727,7 @@
   AST->CompleteTranslationUnit = CompleteTranslationUnit;
   AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
   AST->Invocation = CI;
+  AST->NestedMacroInstantiations = NestedMacroInstantiations;
   
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@@ -1747,7 +1752,8 @@
                                       bool CompleteTranslationUnit,
                                       bool CacheCodeCompletionResults,
                                       bool CXXPrecompilePreamble,
-                                      bool CXXChainedPCH) {
+                                      bool CXXChainedPCH,
+                                      bool NestedMacroInstantiations) {
   if (!Diags.getPtr()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
@@ -1814,6 +1820,7 @@
   AST->NumStoredDiagnosticsInPreamble = StoredDiagnostics.size();
   AST->StoredDiagnostics.swap(StoredDiagnostics);
   AST->Invocation = CI;
+  AST->NestedMacroInstantiations = NestedMacroInstantiations;
   
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@@ -2265,6 +2272,9 @@
     PreprocessorOpts.PrecompiledPreambleBytes.second = false;
   }
 
+  // Disable the preprocessing record
+  PreprocessorOpts.DetailedRecord = false;
+  
   llvm::OwningPtr<SyntaxOnlyAction> Act;
   Act.reset(new SyntaxOnlyAction);
   if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0].second,

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Fri May  6 11:33:08 2011
@@ -227,7 +227,8 @@
   }
 
   if (PPOpts.DetailedRecord)
-    PP->createPreprocessingRecord();
+    PP->createPreprocessingRecord(
+                       PPOpts.DetailedRecordIncludesNestedMacroInstantiations);
   
   InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts);
 

Modified: cfe/trunk/lib/Lex/PreprocessingRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PreprocessingRecord.cpp?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PreprocessingRecord.cpp (original)
+++ cfe/trunk/lib/Lex/PreprocessingRecord.cpp Fri May  6 11:33:08 2011
@@ -45,8 +45,9 @@
   ExternalSource->ReadPreprocessedEntities();
 }
 
-PreprocessingRecord::PreprocessingRecord()
-  : ExternalSource(0), NumPreallocatedEntities(0), 
+PreprocessingRecord::PreprocessingRecord(bool IncludeNestedMacroInstantiations)
+  : IncludeNestedMacroInstantiations(IncludeNestedMacroInstantiations),
+    ExternalSource(0), NumPreallocatedEntities(0), 
     LoadedPreallocatedEntities(false)
 {
 }
@@ -120,6 +121,9 @@
 }
 
 void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI) {
+  if (!IncludeNestedMacroInstantiations && Id.getLocation().isMacroID())
+    return;
+
   if (MacroDefinition *Def = findMacroDefinition(MI))
     PreprocessedEntities.push_back(
                        new (*this) MacroInstantiation(Id.getIdentifierInfo(),

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Fri May  6 11:33:08 2011
@@ -527,10 +527,11 @@
 
 CodeCompletionHandler::~CodeCompletionHandler() { }
 
-void Preprocessor::createPreprocessingRecord() {
+void Preprocessor::createPreprocessingRecord(
+                                      bool IncludeNestedMacroInstantiations) {
   if (Record)
     return;
   
-  Record = new PreprocessingRecord;
+  Record = new PreprocessingRecord(IncludeNestedMacroInstantiations);
   addPPCallbacks(Record);
 }

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri May  6 11:33:08 2011
@@ -2382,7 +2382,7 @@
       PP->getHeaderSearchInfo().SetExternalLookup(this);
     if (TotalNumPreallocatedPreprocessingEntities > 0) {
       if (!PP->getPreprocessingRecord())
-        PP->createPreprocessingRecord();
+        PP->createPreprocessingRecord(true);
       PP->getPreprocessingRecord()->SetExternalSource(*this,
                                      TotalNumPreallocatedPreprocessingEntities);
     }
@@ -2581,7 +2581,7 @@
     TotalNum += Chain[I]->NumPreallocatedPreprocessingEntities;
   if (TotalNum) {
     if (!PP->getPreprocessingRecord())
-      PP->createPreprocessingRecord();
+      PP->createPreprocessingRecord(true);
     PP->getPreprocessingRecord()->SetExternalSource(*this, TotalNum);
   }
 }

Added: cfe/trunk/test/Index/nested-macro-instantiations.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/nested-macro-instantiations.cpp?rev=130990&view=auto
==============================================================================
--- cfe/trunk/test/Index/nested-macro-instantiations.cpp (added)
+++ cfe/trunk/test/Index/nested-macro-instantiations.cpp Fri May  6 11:33:08 2011
@@ -0,0 +1,20 @@
+#define FOO(x) x
+#define BAR(x) FOO(x)
+#define WIBBLE(x) BAR(x)
+
+WIBBLE(int x);
+
+// RUN: env CINDEXTEST_NESTED_MACROS=1 c-index-test -test-load-source all %s | FileCheck -check-prefix CHECK-WITH-NESTED %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_NESTED_MACROS=1 c-index-test -test-load-source all %s | FileCheck -check-prefix CHECK-WITH-NESTED %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_NESTED_MACROS=1 c-index-test -test-load-source-reparse 5 all %s | FileCheck -check-prefix CHECK-WITH-NESTED %s
+// CHECK-WITH-NESTED: nested-macro-instantiations.cpp:5:1: macro instantiation=WIBBLE:3:9 Extent=[5:1 - 5:7]
+// CHECK-WITH-NESTED: nested-macro-instantiations.cpp:3:19: macro instantiation=BAR:2:9 Extent=[3:19 - 5:14]
+// CHECK-WITH-NESTED: nested-macro-instantiations.cpp:2:16: macro instantiation=FOO:1:9 Extent=[2:16 - 5:14]
+// CHECK-WITH-NESTED: nested-macro-instantiations.cpp:5:1: VarDecl=x:5:1 (Definition) Extent=[5:1 - 5:14]
+
+// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix CHECK-WITHOUT-NESTED %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source all %s | FileCheck -check-prefix CHECK-WITHOUT-NESTED %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 all %s | FileCheck -check-prefix CHECK-WITHOUT-NESTED %s
+// CHECK-WITHOUT-NESTED: nested-macro-instantiations.cpp:5:1: macro instantiation=WIBBLE:3:9 Extent=[5:1 - 5:7]
+// CHECK-WITHOUT-NESTED-NOT: nested-macro-instantiations.cpp:3:19: macro instantiation=BAR:2:9 Extent=[3:19 - 5:14]
+// CHECK-WITHOUT-NESTED: nested-macro-instantiations.cpp:5:1: VarDecl=x:5:1 (Definition) Extent=[5:1 - 5:14]

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Fri May  6 11:33:08 2011
@@ -37,6 +37,8 @@
     options |= clang_defaultEditingTranslationUnitOptions();
   if (getenv("CINDEXTEST_COMPLETION_CACHING"))
     options |= CXTranslationUnit_CacheCompletionResults;
+  if (getenv("CINDEXTEST_NESTED_MACROS"))
+    options |= CXTranslationUnit_NestedMacroInstantiations;
   
   return options;
 }
@@ -713,11 +715,11 @@
     return -1;
   }
 
-  TU = clang_createTranslationUnitFromSourceFile(Idx, 0,
-                                                 argc - num_unsaved_files,
-                                                 argv + num_unsaved_files,
-                                                 num_unsaved_files,
-                                                 unsaved_files);
+  TU = clang_parseTranslationUnit(Idx, 0,
+                                  argv + num_unsaved_files,
+                                  argc - num_unsaved_files,
+                                  unsaved_files, num_unsaved_files, 
+                                  getDefaultParsingOptions());
   if (!TU) {
     fprintf(stderr, "Unable to load translation unit!\n");
     free_remapped_files(unsaved_files, num_unsaved_files);
@@ -1231,11 +1233,12 @@
     return -1;
 
   CIdx = clang_createIndex(0, 1);
-  TU = clang_createTranslationUnitFromSourceFile(CIdx, argv[argc - 1],
-                                                 argc - num_unsaved_files - 3,
-                                                 argv + num_unsaved_files + 2,
-                                                 num_unsaved_files,
-                                                 unsaved_files);
+  TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
+                                  argv + num_unsaved_files + 2,
+                                  argc - num_unsaved_files - 3,
+                                  unsaved_files,
+                                  num_unsaved_files,
+                                  getDefaultParsingOptions());
   if (!TU) {
     fprintf(stderr, "unable to parse input\n");
     clang_disposeIndex(CIdx);

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=130990&r1=130989&r2=130990&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri May  6 11:33:08 2011
@@ -2376,10 +2376,12 @@
                                           const char * const *command_line_args,
                                           unsigned num_unsaved_files,
                                           struct CXUnsavedFile *unsaved_files) {
+  unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord |
+                     CXTranslationUnit_NestedMacroInstantiations;
   return clang_parseTranslationUnit(CIdx, source_filename,
                                     command_line_args, num_command_line_args,
                                     unsaved_files, num_unsaved_files,
-                                 CXTranslationUnit_DetailedPreprocessingRecord);
+                                    Options);
 }
   
 struct ParseTranslationUnitInfo {
@@ -2480,9 +2482,12 @@
     Args->push_back(source_filename);
 
   // Do we need the detailed preprocessing record?
+  bool NestedMacroInstantiations = false;
   if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
     Args->push_back("-Xclang");
     Args->push_back("-detailed-preprocessing-record");
+    NestedMacroInstantiations
+      = (options & CXTranslationUnit_NestedMacroInstantiations);
   }
   
   unsigned NumErrors = Diags->getClient()->getNumErrors();
@@ -2501,7 +2506,8 @@
                                  CompleteTranslationUnit,
                                  CacheCodeCompetionResults,
                                  CXXPrecompilePreamble,
-                                 CXXChainedPCH));
+                                 CXXChainedPCH,
+                                 NestedMacroInstantiations));
 
   if (NumErrors != Diags->getClient()->getNumErrors()) {
     // Make sure to check that 'Unit' is non-NULL.





More information about the cfe-commits mailing list