[cfe-commits] r98963 - in /cfe/trunk: include/clang/Driver/CC1Options.td include/clang/Frontend/ASTUnit.h include/clang/Frontend/PCHWriter.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/Frontend/CompilerInvocation.cpp lib/Lex/PreprocessingRecord.cpp lib/Lex/Preprocessor.cpp tools/CIndex/CIndex.cpp

Douglas Gregor dgregor at apple.com
Fri Mar 19 09:15:56 PDT 2010


Author: dgregor
Date: Fri Mar 19 11:15:56 2010
New Revision: 98963

URL: http://llvm.org/viewvc/llvm-project?rev=98963&view=rev
Log:
Optionally store a PreprocessingRecord in the preprocessor itself, and
tie its creation to a CC1 flag -detailed-preprocessing-record.

Modified:
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Frontend/PCHWriter.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/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Lex/PreprocessingRecord.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/tools/CIndex/CIndex.cpp

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Fri Mar 19 11:15:56 2010
@@ -448,7 +448,9 @@
   HelpText<"Undefine the specified macro">;
 def undef : Flag<"-undef">, MetaVarName<"<macro>">,
   HelpText<"undef all system defines">;
-
+def detailed_preprocessing_record : Flag<"-detailed-preprocessing-record">,
+  HelpText<"include a detailed record of preprocessing actions">;
+  
 //===----------------------------------------------------------------------===//
 // Preprocessed Output Options
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Fri Mar 19 11:15:56 2010
@@ -54,7 +54,6 @@
   llvm::OwningPtr<TargetInfo>       Target;
   llvm::OwningPtr<Preprocessor>     PP;
   llvm::OwningPtr<ASTContext>       Ctx;
-  llvm::OwningPtr<PreprocessingRecord> Preprocessing;
   
   /// Optional owned invocation, just used to make the invocation used in
   /// LoadFromCommandLine available.
@@ -137,12 +136,6 @@
   const ASTContext &getASTContext() const { return *Ctx.get(); }
         ASTContext &getASTContext()       { return *Ctx.get(); }
 
-  const PreprocessingRecord &getPreprocessingRecord() const { 
-    return *Preprocessing.get(); 
-  }
-  PreprocessingRecord &getPreprocessingRecord() { return *Preprocessing.get(); }
-  bool hasPreprocessingRecord() { return Preprocessing.get() != 0; }
-    
   const FileManager &getFileManager() const { return FileMgr; }
         FileManager &getFileManager()       { return FileMgr; }
 
@@ -212,8 +205,7 @@
   static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
                                              Diagnostic &Diags,
                                              bool OnlyLocalDecls = false,
-                                             bool CaptureDiagnostics = false,
-                                         bool WantPreprocessingRecord = false);
+                                             bool CaptureDiagnostics = false);
 
   /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
   /// arguments, which must specify exactly one source file.
@@ -236,8 +228,7 @@
                                       bool OnlyLocalDecls = false,
                                       RemappedFile *RemappedFiles = 0,
                                       unsigned NumRemappedFiles = 0,
-                                      bool CaptureDiagnostics = false,
-                                      bool WantPreprocessingRecord = false);
+                                      bool CaptureDiagnostics = false);
 };
 
 } // namespace clang

Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Fri Mar 19 11:15:56 2010
@@ -234,6 +234,9 @@
   ///
   /// \param isysroot if non-NULL, write a relocatable PCH file whose headers
   /// are relative to the given system root.
+  ///
+  /// \param PPRec Record of the preprocessing actions that occurred while
+  /// preprocessing this file, e.g., macro instantiations
   void WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
                 const char* isysroot);
 

Modified: cfe/trunk/include/clang/Frontend/PreprocessorOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PreprocessorOptions.h?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PreprocessorOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/PreprocessorOptions.h Fri Mar 19 11:15:56 2010
@@ -36,6 +36,10 @@
   unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
                               /// and target specific predefines.
 
+  unsigned DetailedRecord : 1; /// Whether we should maintain a detailed
+                               /// record of all macro definitions and
+                               /// instantiations.
+  
   /// The implicit PCH included at the start of the translation unit, or empty.
   std::string ImplicitPCHInclude;
 
@@ -77,7 +81,7 @@
   }
   
 public:
-  PreprocessorOptions() : UsePredefines(true) {}
+  PreprocessorOptions() : UsePredefines(true), DetailedRecord(false) {}
 
   void addMacroDef(llvm::StringRef Name) {
     Macros.push_back(std::make_pair(Name, false));

Modified: cfe/trunk/include/clang/Lex/PreprocessingRecord.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/PreprocessingRecord.h?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/PreprocessingRecord.h (original)
+++ cfe/trunk/include/clang/Lex/PreprocessingRecord.h Fri Mar 19 11:15:56 2010
@@ -14,10 +14,7 @@
 #ifndef LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
 #define LLVM_CLANG_LEX_PREPROCESSINGRECORD_H
 
-#include "clang/Lex/PPCallbacks.h"
 #include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerUnion.h"
 #include "llvm/Support/Allocator.h"
 #include <vector>
 
@@ -206,24 +203,6 @@
     /// \brief Add a new preprocessed entity to this record.
     void addPreprocessedEntity(PreprocessedEntity *Entity);
   };
-  
-  /// \brief Preprocessor callback action used to populate a preprocessing
-  /// record.
-  class PopulatePreprocessingRecord : public PPCallbacks {
-    /// \brief The preprocessing record this action will populate.
-    PreprocessingRecord &Record;
-    
-    /// \brief Mapping from MacroInfo structures to their definitions.
-    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
-
-  public:
-    explicit PopulatePreprocessingRecord(PreprocessingRecord &Record)
-      : Record(Record) { }
-    
-    virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
-    virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
-  };
-  
 } // end namespace clang
 
 inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR,

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Mar 19 11:15:56 2010
@@ -43,7 +43,8 @@
 class TargetInfo;
 class PPCallbacks;
 class DirectoryLookup;
-
+class PreprocessingRecord;
+  
 /// Preprocessor - This object engages in a tight little dance with the lexer to
 /// efficiently preprocess tokens.  Lexers know only about tokens within a
 /// single source file, and don't know anything about preprocessor-level issues
@@ -209,6 +210,13 @@
   unsigned NumCachedTokenLexers;
   TokenLexer *TokenLexerCache[TokenLexerCacheSize];
 
+  /// \brief A record of the macro definitions and instantiations that
+  /// occurred during preprocessing. 
+  ///
+  /// This is an optional side structure that can be enabled with
+  /// \c createPreprocessingRecord() prior to preprocessing.
+  llvm::OwningPtr<PreprocessingRecord> Record;
+  
 private:  // Cached tokens state.
   typedef llvm::SmallVector<Token, 1> CachedTokensTy;
 
@@ -348,6 +356,14 @@
   /// It is an error to remove a handler that has not been registered.
   void RemoveCommentHandler(CommentHandler *Handler);
 
+  /// \brief Retrieve the preprocessing record, or NULL if there is no
+  /// preprocessing record.
+  PreprocessingRecord *getPreprocessingRecord() const { return Record.get(); }
+  
+  /// \brief Create a new preprocessing record, which will keep track of 
+  /// all macro expansions, macro definitions, etc.
+  void createPreprocessingRecord();
+  
   /// EnterMainSourceFile - Enter the specified FileID as the main source file,
   /// which implicitly adds the builtin defines etc.
   bool EnterMainSourceFile();

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Fri Mar 19 11:15:56 2010
@@ -278,8 +278,7 @@
 ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
                                              Diagnostic &Diags,
                                              bool OnlyLocalDecls,
-                                             bool CaptureDiagnostics,
-                                             bool WantPreprocessingRecord) {
+                                             bool CaptureDiagnostics) {
   // Create the compiler instance to use for building the AST.
   CompilerInstance Clang;
   llvm::OwningPtr<ASTUnit> AST;
@@ -329,15 +328,6 @@
   // Create the preprocessor.
   Clang.createPreprocessor();
 
-  // If the ASTUnit was requested to store information about preprocessing,
-  // create storage for that information and attach an appropriate callback to 
-  // populate that storage.
-  if (WantPreprocessingRecord) {
-    AST->Preprocessing.reset(new PreprocessingRecord);
-    Clang.getPreprocessor().addPPCallbacks(
-                          new PopulatePreprocessingRecord(*AST->Preprocessing));
-  }
-      
   Act.reset(new TopLevelDeclTrackerAction(*AST));
   if (!Act->BeginSourceFile(Clang, Clang.getFrontendOpts().Inputs[0].second,
                            /*IsAST=*/false))
@@ -377,8 +367,7 @@
                                       bool OnlyLocalDecls,
                                       RemappedFile *RemappedFiles,
                                       unsigned NumRemappedFiles,
-                                      bool CaptureDiagnostics,
-                                      bool WantPreprocessingRecord) {
+                                      bool CaptureDiagnostics) {
   llvm::SmallVector<const char *, 16> Args;
   Args.push_back("<clang>"); // FIXME: Remove dummy argument.
   Args.insert(Args.end(), ArgBegin, ArgEnd);
@@ -430,6 +419,5 @@
 
   CI->getFrontendOpts().DisableFree = true;
   return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
-                                    CaptureDiagnostics, 
-                                    WantPreprocessingRecord);
+                                    CaptureDiagnostics);
 }

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Fri Mar 19 11:15:56 2010
@@ -224,6 +224,9 @@
     PP->setPTHManager(PTHMgr);
   }
 
+  if (PPOpts.DetailedRecord)
+    PP->createPreprocessingRecord();
+  
   InitializePreprocessor(*PP, PPOpts, HSOpts, FEOpts);
 
   // Handle generating dependencies, if requested.

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Mar 19 11:15:56 2010
@@ -575,6 +575,8 @@
   }
   if (!Opts.UsePredefines)
     Res.push_back("-undef");
+  if (Opts.DetailedRecord)
+    Res.push_back("-detailed-preprocessing-record");
   if (!Opts.ImplicitPCHInclude.empty()) {
     Res.push_back("-include-pch");
     Res.push_back(Opts.ImplicitPCHInclude);
@@ -1232,7 +1234,7 @@
   else
     Opts.TokenCache = Opts.ImplicitPTHInclude;
   Opts.UsePredefines = !Args.hasArg(OPT_undef);
-
+  Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
   // Add macros from the command line.
   for (arg_iterator it = Args.filtered_begin(OPT_D, OPT_U),
          ie = Args.filtered_end(); it != ie; ++it) {

Modified: cfe/trunk/lib/Lex/PreprocessingRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PreprocessingRecord.cpp?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PreprocessingRecord.cpp (original)
+++ cfe/trunk/lib/Lex/PreprocessingRecord.cpp Fri Mar 19 11:15:56 2010
@@ -21,19 +21,3 @@
   PreprocessedEntities.push_back(Entity);
 }
 
-void PopulatePreprocessingRecord::MacroExpands(const Token &Id, 
-                                               const MacroInfo* MI) {
-  Record.addPreprocessedEntity(
-                        new (Record) MacroInstantiation(Id.getIdentifierInfo(),
-                                                       Id.getLocation(),
-                                                        MacroDefinitions[MI]));
-}
-
-void PopulatePreprocessingRecord::MacroDefined(const IdentifierInfo *II, 
-                                               const MacroInfo *MI) {
-  SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
-  MacroDefinition *Def
-    = new (Record) MacroDefinition(II, MI->getDefinitionLoc(), R);
-  MacroDefinitions[MI] = Def;
-  Record.addPreprocessedEntity(Def);
-}

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Fri Mar 19 11:15:56 2010
@@ -31,6 +31,7 @@
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/Pragma.h"
+#include "clang/Lex/PreprocessingRecord.h"
 #include "clang/Lex/ScratchBuffer.h"
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
@@ -627,3 +628,47 @@
 }
 
 CommentHandler::~CommentHandler() { }
+
+namespace {
+  /// \brief Preprocessor callback action used to populate a preprocessing
+  /// record.
+  class PopulatePreprocessingRecord : public PPCallbacks {
+    /// \brief The preprocessing record this action will populate.
+    PreprocessingRecord &Record;
+    
+    /// \brief Mapping from MacroInfo structures to their definitions.
+    llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions;
+    
+  public:
+    explicit PopulatePreprocessingRecord(PreprocessingRecord &Record)
+    : Record(Record) { }
+    
+    virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
+    virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
+  };  
+}
+
+void PopulatePreprocessingRecord::MacroExpands(const Token &Id, 
+                                               const MacroInfo* MI) {
+  Record.addPreprocessedEntity(
+                       new (Record) MacroInstantiation(Id.getIdentifierInfo(),
+                                                       Id.getLocation(),
+                                                       MacroDefinitions[MI]));
+}
+
+void PopulatePreprocessingRecord::MacroDefined(const IdentifierInfo *II, 
+                                               const MacroInfo *MI) {
+  SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
+  MacroDefinition *Def
+  = new (Record) MacroDefinition(II, MI->getDefinitionLoc(), R);
+  MacroDefinitions[MI] = Def;
+  Record.addPreprocessedEntity(Def);
+}
+
+void Preprocessor::createPreprocessingRecord() {
+  if (Record)
+    return;
+  
+  Record.reset(new PreprocessingRecord);
+  addPPCallbacks(new PopulatePreprocessingRecord(*Record));
+}

Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=98963&r1=98962&r2=98963&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Fri Mar 19 11:15:56 2010
@@ -430,11 +430,11 @@
       return true;
 
     // Walk the preprocessing record.
-    if (CXXUnit->hasPreprocessingRecord()) {
+    if (PreprocessingRecord *PPRec
+                       = CXXUnit->getPreprocessor().getPreprocessingRecord()) {
       // FIXME: Once we have the ability to deserialize a preprocessing record,
       // do so.
-      PreprocessingRecord &PPRec = CXXUnit->getPreprocessingRecord();
-      for (PreprocessingRecord::iterator E = PPRec.begin(), EEnd = PPRec.end();
+      for (PreprocessingRecord::iterator E = PPRec->begin(),EEnd = PPRec->end();
            E != EEnd; ++E) {
         if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
           if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit)))
@@ -1014,7 +1014,8 @@
       Args.push_back(source_filename);
     Args.insert(Args.end(), command_line_args,
                 command_line_args + num_command_line_args);
-
+    Args.push_back("-Xclang");
+    Args.push_back("-detailed-preprocessing-record");
     unsigned NumErrors = Diags->getNumErrors();
 
 #ifdef USE_CRASHTRACER
@@ -1028,8 +1029,7 @@
                                    CXXIdx->getOnlyLocalDecls(),
                                    RemappedFiles.data(),
                                    RemappedFiles.size(),
-                                   /*CaptureDiagnostics=*/true,
-                                   /*WantPreprocessingRecord=*/true));
+                                   /*CaptureDiagnostics=*/true));
 
     // FIXME: Until we have broader testing, just drop the entire AST if we
     // encountered an error.
@@ -1114,6 +1114,9 @@
   TemporaryFiles.push_back(DiagnosticsFile);
   argv.push_back("-fdiagnostics-binary");
 
+  argv.push_back("-Xclang");
+  argv.push_back("-detailed-preprocessing-record");
+
   // Add the null terminator.
   argv.push_back(NULL);
 





More information about the cfe-commits mailing list