diff options
| author | John McCall <rjmccall@apple.com> | 2010-06-03 19:28:45 +0000 | 
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2010-06-03 19:28:45 +0000 | 
| commit | 1c70e99a2c18b9a47659c4743f2d5bade3ea85de (patch) | |
| tree | dfb434ec11b1c72a43c40b38e944ae8e5bfa2fd2 /clang/lib | |
| parent | 30093b5d8b4624f7b07f93cc76c211a9b350568f (diff) | |
| download | bcm5719-llvm-1c70e99a2c18b9a47659c4743f2d5bade3ea85de.tar.gz bcm5719-llvm-1c70e99a2c18b9a47659c4743f2d5bade3ea85de.zip | |
Hack in some really terrible C++ record PCH support that I need right now.
This is required in order to test:
The ASTImporter should set base classes after formally entering the definition.
llvm-svn: 105401
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 53 | ||||
| -rw-r--r-- | clang/lib/Frontend/PCHReaderDecl.cpp | 31 | ||||
| -rw-r--r-- | clang/lib/Frontend/PCHWriterDecl.cpp | 17 | 
3 files changed, 76 insertions, 25 deletions
| diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 6ed08d1e1e2..3ccded28c4e 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1687,7 +1687,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {    // Create the record declaration.    RecordDecl *D2 = AdoptDecl;    if (!D2) { -    if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D)) { +    if (isa<CXXRecordDecl>(D)) {        CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),                                                      D->getTagKind(),                                                     DC, Loc, @@ -1695,30 +1695,6 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {                                          Importer.Import(D->getTagKeywordLoc()));        D2 = D2CXX;        D2->setAccess(D->getAccess()); -       -      if (D->isDefinition()) { -        // Add base classes. -        llvm::SmallVector<CXXBaseSpecifier *, 4> Bases; -        for (CXXRecordDecl::base_class_iterator  -                  Base1 = D1CXX->bases_begin(), -               FromBaseEnd = D1CXX->bases_end(); -             Base1 != FromBaseEnd; -             ++Base1) { -          QualType T = Importer.Import(Base1->getType()); -          if (T.isNull()) -            return 0; -           -          Bases.push_back( -            new (Importer.getToContext())  -                  CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()), -                                   Base1->isVirtual(), -                                   Base1->isBaseOfClass(), -                                   Base1->getAccessSpecifierAsWritten(), -                                   T)); -        } -        if (!Bases.empty()) -          D2CXX->setBases(Bases.data(), Bases.size()); -      }      } else {        D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),                                      DC, Loc, @@ -1739,6 +1715,33 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {    if (D->isDefinition()) {      D2->startDefinition(); + +    // Add base classes. +    if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) { +      CXXRecordDecl *D1CXX = cast<CXXRecordDecl>(D); + +      llvm::SmallVector<CXXBaseSpecifier *, 4> Bases; +      for (CXXRecordDecl::base_class_iterator  +                Base1 = D1CXX->bases_begin(), +             FromBaseEnd = D1CXX->bases_end(); +           Base1 != FromBaseEnd; +           ++Base1) { +        QualType T = Importer.Import(Base1->getType()); +        if (T.isNull()) +          return 0; +           +        Bases.push_back( +          new (Importer.getToContext())  +                CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()), +                                 Base1->isVirtual(), +                                 Base1->isBaseOfClass(), +                                 Base1->getAccessSpecifierAsWritten(), +                                 T)); +      } +      if (!Bases.empty()) +        D2CXX->setBases(Bases.data(), Bases.size()); +    } +      ImportDeclContext(D);      D2->completeDefinition();    } diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index 2a1044c447f..606e852385d 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -38,6 +38,8 @@ namespace {                    unsigned &Idx)        : Reader(Reader), Record(Record), Idx(Idx) { } +    CXXBaseSpecifier *ReadCXXBaseSpecifier(); +      void VisitDecl(Decl *D);      void VisitTranslationUnitDecl(TranslationUnitDecl *TU);      void VisitNamedDecl(NamedDecl *ND); @@ -550,9 +552,38 @@ void PCHDeclReader::VisitUnresolvedUsingTypename(    D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));  } +CXXBaseSpecifier *PCHDeclReader::ReadCXXBaseSpecifier() { +  bool isVirtual = static_cast<bool>(Record[Idx++]); +  bool isBaseOfClass = static_cast<bool>(Record[Idx++]); +  AccessSpecifier AS = static_cast<AccessSpecifier>(Record[Idx++]); +  QualType T = Reader.GetType(Record[Idx++]); +  SourceRange Range = Reader.ReadSourceRange(Record, Idx); +  return new (*Reader.getContext()) +    CXXBaseSpecifier(Range, isVirtual, isBaseOfClass, AS, T); +} +  void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {    // assert(false && "cannot read CXXRecordDecl");    VisitRecordDecl(D); + +  // FIXME: this is far from complete + +  if (D->isDefinition()) { +    D->setDefinition(false); // make peace with an assertion +    D->startDefinition(); + +    unsigned NumBases = Record[Idx++]; + +    llvm::SmallVector<CXXBaseSpecifier*, 4> Bases; +    Bases.reserve(NumBases); +    for (unsigned I = 0; I != NumBases; ++I) +      Bases.push_back(ReadCXXBaseSpecifier()); +    D->setBases(Bases.begin(), NumBases); + +    // FIXME: there's a lot of stuff we do here that's kindof sketchy +    // if we're leaving the context incomplete. +    D->completeDefinition(); +  }  }  void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { diff --git a/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp index 42756c35cc3..d0a01f083f9 100644 --- a/clang/lib/Frontend/PCHWriterDecl.cpp +++ b/clang/lib/Frontend/PCHWriterDecl.cpp @@ -105,6 +105,8 @@ namespace {      void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);      void VisitObjCPropertyDecl(ObjCPropertyDecl *D);      void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); + +    void WriteCXXBaseSpecifier(const CXXBaseSpecifier *Base);    };  } @@ -559,9 +561,24 @@ void PCHDeclWriter::VisitUnresolvedUsingTypename(    Code = pch::DECL_UNRESOLVED_USING_TYPENAME;  } +void PCHDeclWriter::WriteCXXBaseSpecifier(const CXXBaseSpecifier *Base) { +  Record.push_back(Base->isVirtual()); +  Record.push_back(Base->isBaseOfClass()); +  Record.push_back(Base->getAccessSpecifierAsWritten()); +  Writer.AddTypeRef(Base->getType(), Record); +  Writer.AddSourceRange(Base->getSourceRange(), Record); +} +  void PCHDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {    // assert(false && "cannot write CXXRecordDecl");    VisitRecordDecl(D); +  if (D->isDefinition()) { +    unsigned NumBases = D->getNumBases(); +    Record.push_back(NumBases); +    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), +           E = D->bases_end(); I != E; ++I) +      WriteCXXBaseSpecifier(&*I); +  }    Code = pch::DECL_CXX_RECORD;  } | 

