diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-03-21 10:50:08 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-03-21 10:50:08 +0000 | 
| commit | c0c7bca4e5b8d12699dc93a0da49e9e4bb79671b (patch) | |
| tree | 508d4388db78f87d35bf26a0400b4b03bc4c1f13 /lib/Frontend/PCHReader.cpp | |
| parent | 4a37f65f1c1373c9956d118a012943de2f61edb0 (diff) | |
Notes
Diffstat (limited to 'lib/Frontend/PCHReader.cpp')
| -rw-r--r-- | lib/Frontend/PCHReader.cpp | 286 | 
1 files changed, 229 insertions, 57 deletions
| diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 49eb2a0e600d5..e659ff047d76b 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -21,6 +21,7 @@  #include "clang/AST/Type.h"  #include "clang/AST/TypeLocVisitor.h"  #include "clang/Lex/MacroInfo.h" +#include "clang/Lex/PreprocessingRecord.h"  #include "clang/Lex/Preprocessor.h"  #include "clang/Lex/HeaderSearch.h"  #include "clang/Basic/OnDiskHashTable.h" @@ -150,7 +151,10 @@ bool PCHValidator::ReadPredefinesBuffer(llvm::StringRef PCHPredef,    std::pair<llvm::StringRef,llvm::StringRef> Split =      llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());    llvm::StringRef Left =  Split.first, Right = Split.second; -  assert(Left != PP.getPredefines() && "Missing PCH include entry!"); +  if (Left == PP.getPredefines()) { +    Error("Missing PCH include entry!"); +    return true; +  }    // If the predefines is equal to the joined left and right halves, we're done!    if (Left.size() + Right.size() == PCHPredef.size() && @@ -300,8 +304,10 @@ bool PCHValidator::ReadPredefinesBuffer(llvm::StringRef PCHPredef,    return false;  } -void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI) { -  PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++); +void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI, +                                      unsigned ID) { +  PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID); +  ++NumHeaderInfos;  }  void PCHValidator::ReadCounter(unsigned Value) { @@ -321,8 +327,9 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,      IdentifierOffsets(0),      MethodPoolLookupTable(0), MethodPoolLookupTableData(0),      TotalSelectorsInMethodPool(0), SelectorOffsets(0), -    TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot), -    NumStatHits(0), NumStatMisses(0), +    TotalNumSelectors(0), MacroDefinitionOffsets(0),  +    NumPreallocatedPreprocessingEntities(0),   +    isysroot(isysroot), NumStatHits(0), NumStatMisses(0),      NumSLocEntriesRead(0), NumStatementsRead(0),      NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),      NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0), @@ -338,8 +345,9 @@ PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,      IdentifierOffsets(0),      MethodPoolLookupTable(0), MethodPoolLookupTableData(0),      TotalSelectorsInMethodPool(0), SelectorOffsets(0), -    TotalNumSelectors(0), Comments(0), NumComments(0), isysroot(isysroot), -    NumStatHits(0), NumStatMisses(0), +    TotalNumSelectors(0), MacroDefinitionOffsets(0),  +    NumPreallocatedPreprocessingEntities(0),   +    isysroot(isysroot), NumStatHits(0), NumStatMisses(0),      NumSLocEntriesRead(0), NumStatementsRead(0),      NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),      NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0), @@ -601,10 +609,8 @@ public:  typedef OnDiskChainedHashTable<PCHIdentifierLookupTrait>    PCHIdentifierLookupTable; -bool PCHReader::Error(const char *Msg) { -  unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Fatal, Msg); -  Diag(DiagID); -  return true; +void PCHReader::Error(const char *Msg) { +  Diag(diag::err_fe_pch_malformed) << Msg;  }  /// \brief Check the contents of the predefines buffer against the @@ -850,17 +856,6 @@ PCHReader::PCHReadResult PCHReader::ReadSourceManagerBlock() {          return Failure;        break; -    case pch::SM_HEADER_FILE_INFO: { -      HeaderFileInfo HFI; -      HFI.isImport = Record[0]; -      HFI.DirInfo = Record[1]; -      HFI.NumIncludes = Record[2]; -      HFI.ControllingMacroID = Record[3]; -      if (Listener) -        Listener->ReadHeaderFileInfo(HFI); -      break; -    } -      case pch::SM_SLOC_FILE_ENTRY:      case pch::SM_SLOC_BUFFER_ENTRY:      case pch::SM_SLOC_INSTANTIATION_ENTRY: @@ -910,6 +905,11 @@ PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {        return Failure;      } +    if (Record.size() < 8) { +      Error("source location entry is incorrect"); +      return Failure; +    } +      FileID FID = SourceMgr.createFileID(File,                                  SourceLocation::getFromRawEncoding(Record[1]),                                         (SrcMgr::CharacteristicKind)Record[2], @@ -918,6 +918,14 @@ PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {        const_cast<SrcMgr::FileInfo&>(SourceMgr.getSLocEntry(FID).getFile())          .setHasLineDirectives(); +    // Reconstruct header-search information for this file. +    HeaderFileInfo HFI; +    HFI.isImport = Record[4]; +    HFI.DirInfo = Record[5]; +    HFI.NumIncludes = Record[6]; +    HFI.ControllingMacroID = Record[7]; +    if (Listener) +      Listener->ReadHeaderFileInfo(HFI, File->getUID());      break;    } @@ -928,8 +936,12 @@ PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {      Record.clear();      unsigned RecCode        = SLocEntryCursor.ReadRecord(Code, Record, &BlobStart, &BlobLen); -    assert(RecCode == pch::SM_SLOC_BUFFER_BLOB && "Ill-formed PCH file"); -    (void)RecCode; + +    if (RecCode != pch::SM_SLOC_BUFFER_BLOB) { +      Error("PCH record has invalid code"); +      return Failure; +    } +      llvm::MemoryBuffer *Buffer        = llvm::MemoryBuffer::getMemBuffer(BlobStart,                                           BlobStart + BlobLen - 1, @@ -1038,12 +1050,14 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {        MacroInfo *MI = PP->AllocateMacroInfo(Loc);        MI->setIsUsed(isUsed); +      unsigned NextIndex = 3;        if (RecType == pch::PP_MACRO_FUNCTION_LIKE) {          // Decode function-like macro info.          bool isC99VarArgs = Record[3];          bool isGNUVarArgs = Record[4];          MacroArgs.clear();          unsigned NumArgs = Record[5]; +        NextIndex = 6 + NumArgs;          for (unsigned i = 0; i != NumArgs; ++i)            MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i])); @@ -1061,6 +1075,13 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {        // Remember that we saw this macro last so that we add the tokens that        // form its body to it.        Macro = MI; +       +      if (NextIndex + 1 == Record.size() && PP->getPreprocessingRecord()) { +        // We have a macro definition. Load it now. +        PP->getPreprocessingRecord()->RegisterMacroDefinition(Macro, +                                        getMacroDefinition(Record[NextIndex])); +      } +              ++NumMacrosRead;        break;      } @@ -1081,6 +1102,64 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {        Macro->AddTokenToBody(Tok);        break;      } +         +    case pch::PP_MACRO_INSTANTIATION: { +      // If we already have a macro, that means that we've hit the end +      // of the definition of the macro we were looking for. We're +      // done. +      if (Macro) +        return; +       +      if (!PP->getPreprocessingRecord()) { +        Error("missing preprocessing record in PCH file"); +        return; +      } +         +      PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); +      if (PPRec.getPreprocessedEntity(Record[0])) +        return; + +      MacroInstantiation *MI +        = new (PPRec) MacroInstantiation(DecodeIdentifierInfo(Record[3]), +                               SourceRange( +                                 SourceLocation::getFromRawEncoding(Record[1]), +                                 SourceLocation::getFromRawEncoding(Record[2])), +                                         getMacroDefinition(Record[4])); +      PPRec.SetPreallocatedEntity(Record[0], MI); +      return; +    } + +    case pch::PP_MACRO_DEFINITION: { +      // If we already have a macro, that means that we've hit the end +      // of the definition of the macro we were looking for. We're +      // done. +      if (Macro) +        return; +       +      if (!PP->getPreprocessingRecord()) { +        Error("missing preprocessing record in PCH file"); +        return; +      } +       +      PreprocessingRecord &PPRec = *PP->getPreprocessingRecord(); +      if (PPRec.getPreprocessedEntity(Record[0])) +        return; +         +      if (Record[1] >= MacroDefinitionsLoaded.size()) { +        Error("out-of-bounds macro definition record"); +        return; +      } + +      MacroDefinition *MD +        = new (PPRec) MacroDefinition(DecodeIdentifierInfo(Record[4]), +                                SourceLocation::getFromRawEncoding(Record[5]), +                              SourceRange( +                                SourceLocation::getFromRawEncoding(Record[2]), +                                SourceLocation::getFromRawEncoding(Record[3]))); +      PPRec.SetPreallocatedEntity(Record[0], MD); +      MacroDefinitionsLoaded[Record[1]] = MD; +      return; +    }    }    }  } @@ -1130,16 +1209,32 @@ void PCHReader::ReadDefinedMacros() {      case pch::PP_MACRO_OBJECT_LIKE:      case pch::PP_MACRO_FUNCTION_LIKE: -        DecodeIdentifierInfo(Record[0]); +      DecodeIdentifierInfo(Record[0]);        break;      case pch::PP_TOKEN:        // Ignore tokens.        break; +         +    case pch::PP_MACRO_INSTANTIATION: +    case pch::PP_MACRO_DEFINITION: +      // Read the macro record. +      ReadMacroRecord(Cursor.GetCurrentBitNo()); +      break;      }    }  } +MacroDefinition *PCHReader::getMacroDefinition(pch::IdentID ID) { +  if (ID == 0 || ID >= MacroDefinitionsLoaded.size()) +    return 0; +   +  if (!MacroDefinitionsLoaded[ID]) +    ReadMacroRecord(MacroDefinitionOffsets[ID]); +     +  return MacroDefinitionsLoaded[ID]; +} +  /// \brief If we are loading a relocatable PCH file, and the filename is  /// not an absolute path, add the system root to the beginning of the file  /// name. @@ -1408,11 +1503,6 @@ PCHReader::ReadPCHBlock() {        MaybeAddSystemRootToFilename(OriginalFileName);        break; -    case pch::COMMENT_RANGES: -      Comments = (SourceRange *)BlobStart; -      NumComments = BlobLen / sizeof(SourceRange); -      break; -      case pch::VERSION_CONTROL_BRANCH_REVISION: {        const std::string &CurBranch = getClangFullRepositoryVersion();        llvm::StringRef PCHBranch(BlobStart, BlobLen); @@ -1422,6 +1512,19 @@ PCHReader::ReadPCHBlock() {        }        break;      } +         +    case pch::MACRO_DEFINITION_OFFSETS: +      MacroDefinitionOffsets = (const uint32_t *)BlobStart; +      if (PP) { +        if (!PP->getPreprocessingRecord()) +          PP->createPreprocessingRecord(); +        PP->getPreprocessingRecord()->SetExternalSource(*this, Record[0]); +      } else { +        NumPreallocatedPreprocessingEntities = Record[0]; +      } +        +      MacroDefinitionsLoaded.resize(Record[1]); +      break;      }    }    Error("premature end of bitstream in PCH file"); @@ -1553,6 +1656,18 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {    return Success;  } +void PCHReader::setPreprocessor(Preprocessor &pp) { +  PP = &pp; +   +  if (NumPreallocatedPreprocessingEntities) { +    if (!PP->getPreprocessingRecord()) +      PP->createPreprocessingRecord(); +    PP->getPreprocessingRecord()->SetExternalSource(*this,  +                                          NumPreallocatedPreprocessingEntities); +    NumPreallocatedPreprocessingEntities = 0; +  } +} +  void PCHReader::InitializeContext(ASTContext &Ctx) {    Context = &Ctx;    assert(Context && "Passed null context!"); @@ -1584,29 +1699,44 @@ void PCHReader::InitializeContext(ASTContext &Ctx) {      Context->setObjCFastEnumerationStateType(GetType(FastEnum));    if (unsigned File = SpecialTypes[pch::SPECIAL_TYPE_FILE]) {      QualType FileType = GetType(File); -    assert(!FileType.isNull() && "FILE type is NULL"); +    if (FileType.isNull()) { +      Error("FILE type is NULL"); +      return; +    }      if (const TypedefType *Typedef = FileType->getAs<TypedefType>())        Context->setFILEDecl(Typedef->getDecl());      else {        const TagType *Tag = FileType->getAs<TagType>(); -      assert(Tag && "Invalid FILE type in PCH file"); +      if (!Tag) { +        Error("Invalid FILE type in PCH file"); +        return; +      }        Context->setFILEDecl(Tag->getDecl());      }    }    if (unsigned Jmp_buf = SpecialTypes[pch::SPECIAL_TYPE_jmp_buf]) {      QualType Jmp_bufType = GetType(Jmp_buf); -    assert(!Jmp_bufType.isNull() && "jmp_bug type is NULL"); +    if (Jmp_bufType.isNull()) { +      Error("jmp_bug type is NULL"); +      return; +    }      if (const TypedefType *Typedef = Jmp_bufType->getAs<TypedefType>())        Context->setjmp_bufDecl(Typedef->getDecl());      else {        const TagType *Tag = Jmp_bufType->getAs<TagType>(); -      assert(Tag && "Invalid jmp_bug type in PCH file"); +      if (!Tag) { +        Error("Invalid jmp_bug type in PCH file"); +        return; +      }        Context->setjmp_bufDecl(Tag->getDecl());      }    }    if (unsigned Sigjmp_buf = SpecialTypes[pch::SPECIAL_TYPE_sigjmp_buf]) {      QualType Sigjmp_bufType = GetType(Sigjmp_buf); -    assert(!Sigjmp_bufType.isNull() && "sigjmp_buf type is NULL"); +    if (Sigjmp_bufType.isNull()) { +      Error("sigjmp_buf type is NULL"); +      return; +    }      if (const TypedefType *Typedef = Sigjmp_bufType->getAs<TypedefType>())        Context->setsigjmp_bufDecl(Typedef->getDecl());      else { @@ -1799,10 +1929,8 @@ bool PCHReader::ParseLanguageOptions(    return false;  } -void PCHReader::ReadComments(std::vector<SourceRange> &Comments) { -  Comments.resize(NumComments); -  std::copy(this->Comments, this->Comments + NumComments, -            Comments.begin()); +void PCHReader::ReadPreprocessedEntities() { +  ReadDefinedMacros();  }  /// \brief Read and return the type at the given offset. @@ -1823,45 +1951,65 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {    unsigned Code = DeclsCursor.ReadCode();    switch ((pch::TypeCode)DeclsCursor.ReadRecord(Code, Record)) {    case pch::TYPE_EXT_QUAL: { -    assert(Record.size() == 2 && -           "Incorrect encoding of extended qualifier type"); +    if (Record.size() != 2) { +      Error("Incorrect encoding of extended qualifier type"); +      return QualType(); +    }      QualType Base = GetType(Record[0]);      Qualifiers Quals = Qualifiers::fromOpaqueValue(Record[1]);      return Context->getQualifiedType(Base, Quals);    }    case pch::TYPE_COMPLEX: { -    assert(Record.size() == 1 && "Incorrect encoding of complex type"); +    if (Record.size() != 1) { +      Error("Incorrect encoding of complex type"); +      return QualType(); +    }      QualType ElemType = GetType(Record[0]);      return Context->getComplexType(ElemType);    }    case pch::TYPE_POINTER: { -    assert(Record.size() == 1 && "Incorrect encoding of pointer type"); +    if (Record.size() != 1) { +      Error("Incorrect encoding of pointer type"); +      return QualType(); +    }      QualType PointeeType = GetType(Record[0]);      return Context->getPointerType(PointeeType);    }    case pch::TYPE_BLOCK_POINTER: { -    assert(Record.size() == 1 && "Incorrect encoding of block pointer type"); +    if (Record.size() != 1) { +      Error("Incorrect encoding of block pointer type"); +      return QualType(); +    }      QualType PointeeType = GetType(Record[0]);      return Context->getBlockPointerType(PointeeType);    }    case pch::TYPE_LVALUE_REFERENCE: { -    assert(Record.size() == 1 && "Incorrect encoding of lvalue reference type"); +    if (Record.size() != 1) { +      Error("Incorrect encoding of lvalue reference type"); +      return QualType(); +    }      QualType PointeeType = GetType(Record[0]);      return Context->getLValueReferenceType(PointeeType);    }    case pch::TYPE_RVALUE_REFERENCE: { -    assert(Record.size() == 1 && "Incorrect encoding of rvalue reference type"); +    if (Record.size() != 1) { +      Error("Incorrect encoding of rvalue reference type"); +      return QualType(); +    }      QualType PointeeType = GetType(Record[0]);      return Context->getRValueReferenceType(PointeeType);    }    case pch::TYPE_MEMBER_POINTER: { -    assert(Record.size() == 1 && "Incorrect encoding of member pointer type"); +    if (Record.size() != 1) { +      Error("Incorrect encoding of member pointer type"); +      return QualType(); +    }      QualType PointeeType = GetType(Record[0]);      QualType ClassType = GetType(Record[1]);      return Context->getMemberPointerType(PointeeType, ClassType.getTypePtr()); @@ -1957,7 +2105,10 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {               cast<UnresolvedUsingTypenameDecl>(GetDecl(Record[0])));    case pch::TYPE_TYPEDEF: -    assert(Record.size() == 1 && "incorrect encoding of typedef type"); +    if (Record.size() != 1) { +      Error("incorrect encoding of typedef type"); +      return QualType(); +    }      return Context->getTypeDeclType(cast<TypedefDecl>(GetDecl(Record[0])));    case pch::TYPE_TYPEOF_EXPR: @@ -1976,15 +2127,24 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {      return Context->getDecltypeType(ReadTypeExpr());    case pch::TYPE_RECORD: -    assert(Record.size() == 1 && "incorrect encoding of record type"); +    if (Record.size() != 1) { +      Error("incorrect encoding of record type"); +      return QualType(); +    }      return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));    case pch::TYPE_ENUM: -    assert(Record.size() == 1 && "incorrect encoding of enum type"); +    if (Record.size() != 1) { +      Error("incorrect encoding of enum type"); +      return QualType(); +    }      return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0])));    case pch::TYPE_ELABORATED: { -    assert(Record.size() == 2 && "incorrect encoding of elaborated type"); +    if (Record.size() != 2) { +      Error("incorrect encoding of elaborated type"); +      return QualType(); +    }      unsigned Tag = Record[1];      return Context->getElaboratedType(GetType(Record[0]),                                        (ElaboratedType::TagKind) Tag); @@ -2329,8 +2489,12 @@ bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,                                    llvm::SmallVectorImpl<pch::DeclID> &Decls) {    assert(DC->hasExternalLexicalStorage() &&           "DeclContext has no lexical decls in storage"); +    uint64_t Offset = DeclContextOffsets[DC].first; -  assert(Offset && "DeclContext has no lexical decls in storage"); +  if (Offset == 0) { +    Error("DeclContext has no lexical decls in storage"); +    return true; +  }    // Keep track of where we are in the stream, then jump back there    // after reading this context. @@ -2342,8 +2506,10 @@ bool PCHReader::ReadDeclsLexicallyInContext(DeclContext *DC,    RecordData Record;    unsigned Code = DeclsCursor.ReadCode();    unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); -  (void)RecCode; -  assert(RecCode == pch::DECL_CONTEXT_LEXICAL && "Expected lexical block"); +  if (RecCode != pch::DECL_CONTEXT_LEXICAL) { +    Error("Expected lexical block"); +    return true; +  }    // Load all of the declaration IDs    Decls.clear(); @@ -2357,7 +2523,10 @@ bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,    assert(DC->hasExternalVisibleStorage() &&           "DeclContext has no visible decls in storage");    uint64_t Offset = DeclContextOffsets[DC].second; -  assert(Offset && "DeclContext has no visible decls in storage"); +  if (Offset == 0) { +    Error("DeclContext has no visible decls in storage"); +    return true; +  }    // Keep track of where we are in the stream, then jump back there    // after reading this context. @@ -2369,8 +2538,11 @@ bool PCHReader::ReadDeclsVisibleInContext(DeclContext *DC,    RecordData Record;    unsigned Code = DeclsCursor.ReadCode();    unsigned RecCode = DeclsCursor.ReadRecord(Code, Record); -  (void)RecCode; -  assert(RecCode == pch::DECL_CONTEXT_VISIBLE && "Expected visible block"); +  if (RecCode != pch::DECL_CONTEXT_VISIBLE) { +    Error("Expected visible block"); +    return true; +  } +    if (Record.size() == 0)      return false; | 
