zcov: / include/clang/Frontend/PCHWriter.h


Files: 1 Branches Taken: 50.0% 4 / 8
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 8 / 8
Line Coverage: 100.0% 26 / 26


Programs: 3 Runs 8691


       1                 : //===--- PCHWriter.h - Precompiled Headers Writer ---------------*- C++ -*-===//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : //  This file defines the PCHWriter class, which writes a precompiled
      11                 : //  header containing a serialized representation of a translation
      12                 : //  unit.
      13                 : //
      14                 : //===----------------------------------------------------------------------===//
      15                 : #ifndef LLVM_CLANG_FRONTEND_PCH_WRITER_H
      16                 : #define LLVM_CLANG_FRONTEND_PCH_WRITER_H
      17                 : 
      18                 : #include "clang/AST/Decl.h"
      19                 : #include "clang/AST/DeclarationName.h"
      20                 : #include "clang/Frontend/PCHBitCodes.h"
      21                 : #include "llvm/ADT/DenseMap.h"
      22                 : #include "llvm/ADT/SmallVector.h"
      23                 : #include <map>
      24                 : #include <queue>
      25                 : 
      26                 : namespace llvm {
      27                 :   class APFloat;
      28                 :   class APInt;
      29                 :   class BitstreamWriter;
      30                 : }
      31                 : 
      32                 : namespace clang {
      33                 : 
      34                 : class ASTContext;
      35                 : class LabelStmt;
      36                 : class MemorizeStatCalls;
      37                 : class Preprocessor;
      38                 : class Sema;
      39                 : class SourceManager;
      40                 : class SwitchCase;
      41                 : class TargetInfo;
      42                 : 
      43                 : /// A structure for putting "fast"-unqualified QualTypes into a
      44                 : /// DenseMap.  This uses the standard pointer hash function.
      45                 : struct UnsafeQualTypeDenseMapInfo {
      46             8030:   static inline bool isEqual(QualType A, QualType B) { return A == B; }
      47             1697:   static inline QualType getEmptyKey() {
      48             1697:     return QualType::getFromOpaquePtr((void*) 1);
      49                 :   }
      50             1280:   static inline QualType getTombstoneKey() {
      51             1280:     return QualType::getFromOpaquePtr((void*) 2);
      52                 :   }
      53             1236:   static inline unsigned getHashValue(QualType T) {
      54                 :     assert(!T.getLocalFastQualifiers() && 
                     1236: branch 1 taken
                        0: branch 2 not taken
      55             1236:            "hash invalid for types with fast quals");
      56             1236:     uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
      57             1236:     return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
      58                 :   }
      59                 : };
      60                 : 
      61                 : /// \brief Writes a precompiled header containing the contents of a
      62                 : /// translation unit.
      63                 : ///
      64                 : /// The PCHWriter class produces a bitstream containing the serialized
      65                 : /// representation of a given abstract syntax tree and its supporting
      66                 : /// data structures. This bitstream can be de-serialized via an
      67                 : /// instance of the PCHReader class.
      68               44: class PCHWriter {
      69                 : public:
      70                 :   typedef llvm::SmallVector<uint64_t, 64> RecordData;
      71                 : 
      72                 : private:
      73                 :   /// \brief The bitstream writer used to emit this precompiled header.
      74                 :   llvm::BitstreamWriter &Stream;
      75                 : 
      76                 :   /// \brief Stores a declaration or a type to be written to the PCH file.
      77              975:   class DeclOrType {
      78                 :   public:
      79              602:     DeclOrType(Decl *D) : Stored(D), IsType(false) { }
      80              373:     DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
      81                 :     
      82             1348:     bool isType() const { return IsType; }
      83              602:     bool isDecl() const { return !IsType; }
      84                 :     
      85              373:     QualType getType() const {
                      373: branch 1 taken
                        0: branch 2 not taken
      86              373:       assert(isType() && "Not a type!");
      87              373:       return QualType::getFromOpaquePtr(Stored);
      88                 :     }
      89                 :     
      90              602:     Decl *getDecl() const {
                      602: branch 1 taken
                        0: branch 2 not taken
      91              602:       assert(isDecl() && "Not a decl!");
      92              602:       return static_cast<Decl *>(Stored);
      93                 :     }
      94                 :     
      95                 :   private:
      96                 :     void *Stored;
      97                 :     bool IsType;
      98                 :   };
      99                 :   
     100                 :   /// \brief The declarations and types to emit.
     101                 :   std::queue<DeclOrType> DeclTypesToEmit;
     102                 :   
     103                 :   /// \brief Map that provides the ID numbers of each declaration within
     104                 :   /// the output stream.
     105                 :   ///
     106                 :   /// The ID numbers of declarations are consecutive (in order of
     107                 :   /// discovery) and start at 2. 1 is reserved for the translation
     108                 :   /// unit, while 0 is reserved for NULL.
     109                 :   llvm::DenseMap<const Decl *, pch::DeclID> DeclIDs;
     110                 : 
     111                 :   /// \brief Offset of each declaration in the bitstream, indexed by
     112                 :   /// the declaration's ID.
     113                 :   std::vector<uint32_t> DeclOffsets;
     114                 : 
     115                 :   /// \brief Map that provides the ID numbers of each type within the
     116                 :   /// output stream.
     117                 :   ///
     118                 :   /// The ID numbers of types are consecutive (in order of discovery)
     119                 :   /// and start at 1. 0 is reserved for NULL. When types are actually
     120                 :   /// stored in the stream, the ID number is shifted by 2 bits to
     121                 :   /// allow for the const/volatile qualifiers.
     122                 :   ///
     123                 :   /// Keys in the map never have const/volatile qualifiers.
     124                 :   llvm::DenseMap<QualType, pch::TypeID, UnsafeQualTypeDenseMapInfo> TypeIDs;
     125                 : 
     126                 :   /// \brief Offset of each type in the bitstream, indexed by
     127                 :   /// the type's ID.
     128                 :   std::vector<uint32_t> TypeOffsets;
     129                 : 
     130                 :   /// \brief The type ID that will be assigned to the next new type.
     131                 :   pch::TypeID NextTypeID;
     132                 : 
     133                 :   /// \brief Map that provides the ID numbers of each identifier in
     134                 :   /// the output stream.
     135                 :   ///
     136                 :   /// The ID numbers for identifiers are consecutive (in order of
     137                 :   /// discovery), starting at 1. An ID of zero refers to a NULL
     138                 :   /// IdentifierInfo.
     139                 :   llvm::DenseMap<const IdentifierInfo *, pch::IdentID> IdentifierIDs;
     140                 : 
     141                 :   /// \brief Offsets of each of the identifier IDs into the identifier
     142                 :   /// table.
     143                 :   std::vector<uint32_t> IdentifierOffsets;
     144                 : 
     145                 :   /// \brief Map that provides the ID numbers of each Selector.
     146                 :   llvm::DenseMap<Selector, pch::SelectorID> SelectorIDs;
     147                 : 
     148                 :   /// \brief Offset of each selector within the method pool/selector
     149                 :   /// table, indexed by the Selector ID (-1).
     150                 :   std::vector<uint32_t> SelectorOffsets;
     151                 : 
     152                 :   /// \brief A vector of all Selectors (ordered by ID).
     153                 :   std::vector<Selector> SelVector;
     154                 : 
     155                 :   /// \brief Offsets of each of the macro identifiers into the
     156                 :   /// bitstream.
     157                 :   ///
     158                 :   /// For each identifier that is associated with a macro, this map
     159                 :   /// provides the offset into the bitstream where that macro is
     160                 :   /// defined.
     161                 :   llvm::DenseMap<const IdentifierInfo *, uint64_t> MacroOffsets;
     162                 : 
     163                 :   /// \brief Declarations encountered that might be external
     164                 :   /// definitions.
     165                 :   ///
     166                 :   /// We keep track of external definitions (as well as tentative
     167                 :   /// definitions) as we are emitting declarations to the PCH
     168                 :   /// file. The PCH file contains a separate record for these external
     169                 :   /// definitions, which are provided to the AST consumer by the PCH
     170                 :   /// reader. This is behavior is required to properly cope with,
     171                 :   /// e.g., tentative variable definitions that occur within
     172                 :   /// headers. The declarations themselves are stored as declaration
     173                 :   /// IDs, since they will be written out to an EXTERNAL_DEFINITIONS
     174                 :   /// record.
     175                 :   llvm::SmallVector<uint64_t, 16> ExternalDefinitions;
     176                 : 
     177                 :   /// \brief Statements that we've encountered while serializing a
     178                 :   /// declaration or type.
     179                 :   llvm::SmallVector<Stmt *, 8> StmtsToEmit;
     180                 : 
     181                 :   /// \brief Mapping from SwitchCase statements to IDs.
     182                 :   std::map<SwitchCase *, unsigned> SwitchCaseIDs;
     183                 : 
     184                 :   /// \brief Mapping from LabelStmt statements to IDs.
     185                 :   std::map<LabelStmt *, unsigned> LabelIDs;
     186                 : 
     187                 :   /// \brief The number of statements written to the PCH file.
     188                 :   unsigned NumStatements;
     189                 : 
     190                 :   /// \brief The number of macros written to the PCH file.
     191                 :   unsigned NumMacros;
     192                 : 
     193                 :   /// \brief The number of lexical declcontexts written to the PCH
     194                 :   /// file.
     195                 :   unsigned NumLexicalDeclContexts;
     196                 : 
     197                 :   /// \brief The number of visible declcontexts written to the PCH
     198                 :   /// file.
     199                 :   unsigned NumVisibleDeclContexts;
     200                 : 
     201                 :   void WriteBlockInfoBlock();
     202                 :   void WriteMetadata(ASTContext &Context, const char *isysroot);
     203                 :   void WriteLanguageOptions(const LangOptions &LangOpts);
     204                 :   void WriteStatCache(MemorizeStatCalls &StatCalls, const char* isysroot);
     205                 :   void WriteSourceManagerBlock(SourceManager &SourceMgr,
     206                 :                                const Preprocessor &PP,
     207                 :                                const char* isysroot);
     208                 :   void WritePreprocessor(const Preprocessor &PP);
     209                 :   void WriteComments(ASTContext &Context);
     210                 :   void WriteType(QualType T);
     211                 :   uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
     212                 :   uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
     213                 : 
     214                 :   void WriteMethodPool(Sema &SemaRef);
     215                 :   void WriteIdentifierTable(Preprocessor &PP);
     216                 :   void WriteAttributeRecord(const Attr *Attr);
     217                 : 
     218                 :   unsigned ParmVarDeclAbbrev;
     219                 :   void WriteDeclsBlockAbbrevs();
     220                 :   void WriteDecl(ASTContext &Context, Decl *D);
     221                 :   
     222                 : public:
     223                 :   /// \brief Create a new precompiled header writer that outputs to
     224                 :   /// the given bitstream.
     225                 :   PCHWriter(llvm::BitstreamWriter &Stream);
     226                 : 
     227                 :   /// \brief Write a precompiled header for the given semantic analysis.
     228                 :   ///
     229                 :   /// \param SemaRef a reference to the semantic analysis object that processed
     230                 :   /// the AST to be written into the precompiled header.
     231                 :   ///
     232                 :   /// \param StatCalls the object that cached all of the stat() calls made while
     233                 :   /// searching for source files and headers.
     234                 :   ///
     235                 :   /// \param isysroot if non-NULL, write a relocatable PCH file whose headers
     236                 :   /// are relative to the given system root.
     237                 :   void WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
     238                 :                 const char* isysroot);
     239                 : 
     240                 :   /// \brief Emit a source location.
     241                 :   void AddSourceLocation(SourceLocation Loc, RecordData &Record);
     242                 : 
     243                 :   /// \brief Emit an integral value.
     244                 :   void AddAPInt(const llvm::APInt &Value, RecordData &Record);
     245                 : 
     246                 :   /// \brief Emit a signed integral value.
     247                 :   void AddAPSInt(const llvm::APSInt &Value, RecordData &Record);
     248                 : 
     249                 :   /// \brief Emit a floating-point value.
     250                 :   void AddAPFloat(const llvm::APFloat &Value, RecordData &Record);
     251                 : 
     252                 :   /// \brief Emit a reference to an identifier
     253                 :   void AddIdentifierRef(const IdentifierInfo *II, RecordData &Record);
     254                 : 
     255                 :   /// \brief Emit a Selector (which is a smart pointer reference)
     256                 :   void AddSelectorRef(const Selector, RecordData &Record);
     257                 : 
     258                 :   /// \brief Get the unique number used to refer to the given
     259                 :   /// identifier.
     260                 :   pch::IdentID getIdentifierRef(const IdentifierInfo *II);
     261                 : 
     262                 :   /// \brief Retrieve the offset of the macro definition for the given
     263                 :   /// identifier.
     264                 :   ///
     265                 :   /// The identifier must refer to a macro.
     266             4649:   uint64_t getMacroOffset(const IdentifierInfo *II) {
     267                 :     assert(MacroOffsets.find(II) != MacroOffsets.end() &&
                     4649: branch 4 taken
                        0: branch 5 not taken
     268             4649:            "Identifier does not name a macro");
     269             4649:     return MacroOffsets[II];
     270                 :   }
     271                 : 
     272                 :   /// \brief Emit a reference to a type.
     273                 :   void AddTypeRef(QualType T, RecordData &Record);
     274                 : 
     275                 :   /// \brief Emits a reference to a declarator info.
     276                 :   void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordData &Record);
     277                 : 
     278                 :   /// \brief Emits a template argument location.
     279                 :   void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
     280                 :                               RecordData &Record);
     281                 : 
     282                 :   /// \brief Emit a reference to a declaration.
     283                 :   void AddDeclRef(const Decl *D, RecordData &Record);
     284                 : 
     285                 :   /// \brief Determine the declaration ID of an already-emitted
     286                 :   /// declaration.
     287                 :   pch::DeclID getDeclID(const Decl *D);
     288                 : 
     289                 :   /// \brief Emit a declaration name.
     290                 :   void AddDeclarationName(DeclarationName Name, RecordData &Record);
     291                 : 
     292                 :   /// \brief Add a string to the given record.
     293                 :   void AddString(const std::string &Str, RecordData &Record);
     294                 : 
     295                 :   /// \brief Note that the identifier II occurs at the given offset
     296                 :   /// within the identifier table.
     297                 :   void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
     298                 : 
     299                 :   /// \brief Note that the selector Sel occurs at the given offset
     300                 :   /// within the method pool/selector table.
     301                 :   void SetSelectorOffset(Selector Sel, uint32_t Offset);
     302                 : 
     303                 :   /// \brief Add the given statement or expression to the queue of
     304                 :   /// statements to emit.
     305                 :   ///
     306                 :   /// This routine should be used when emitting types and declarations
     307                 :   /// that have expressions as part of their formulation. Once the
     308                 :   /// type or declaration has been written, call FlushStmts() to write
     309                 :   /// the corresponding statements just after the type or
     310                 :   /// declaration.
     311              116:   void AddStmt(Stmt *S) { StmtsToEmit.push_back(S); }
     312                 : 
     313                 :   /// \brief Write the given subexpression to the bitstream.
     314                 :   void WriteSubStmt(Stmt *S);
     315                 : 
     316                 :   /// \brief Flush all of the statements and expressions that have
     317                 :   /// been added to the queue via AddStmt().
     318                 :   void FlushStmts();
     319                 : 
     320                 :   /// \brief Record an ID for the given switch-case statement.
     321                 :   unsigned RecordSwitchCaseID(SwitchCase *S);
     322                 : 
     323                 :   /// \brief Retrieve the ID for the given switch-case statement.
     324                 :   unsigned getSwitchCaseID(SwitchCase *S);
     325                 : 
     326                 :   /// \brief Retrieve the ID for the given label statement, which may
     327                 :   /// or may not have been emitted yet.
     328                 :   unsigned GetLabelID(LabelStmt *S);
     329                 : 
     330               13:   unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; }
     331                 : };
     332                 : 
     333                 : } // end namespace clang
     334                 : 
     335                 : #endif

Generated: 2010-02-10 01:31 by zcov