head	1.1;
branch	1.1.1;
access;
symbols
	netbsd-11-0-RC4:1.1.1.9
	netbsd-11-0-RC3:1.1.1.9
	netbsd-11-0-RC2:1.1.1.9
	netbsd-11-0-RC1:1.1.1.9
	perseant-exfatfs-base-20250801:1.1.1.9
	netbsd-11:1.1.1.9.0.10
	netbsd-11-base:1.1.1.9
	netbsd-10-1-RELEASE:1.1.1.9
	perseant-exfatfs-base-20240630:1.1.1.9
	perseant-exfatfs:1.1.1.9.0.8
	perseant-exfatfs-base:1.1.1.9
	netbsd-8-3-RELEASE:1.1.1.7
	netbsd-9-4-RELEASE:1.1.1.8
	netbsd-10-0-RELEASE:1.1.1.9
	netbsd-10-0-RC6:1.1.1.9
	netbsd-10-0-RC5:1.1.1.9
	netbsd-10-0-RC4:1.1.1.9
	netbsd-10-0-RC3:1.1.1.9
	netbsd-10-0-RC2:1.1.1.9
	netbsd-10-0-RC1:1.1.1.9
	netbsd-10:1.1.1.9.0.6
	netbsd-10-base:1.1.1.9
	netbsd-9-3-RELEASE:1.1.1.8
	cjep_sun2x:1.1.1.9.0.4
	cjep_sun2x-base:1.1.1.9
	cjep_staticlib_x-base1:1.1.1.9
	netbsd-9-2-RELEASE:1.1.1.8
	cjep_staticlib_x:1.1.1.9.0.2
	cjep_staticlib_x-base:1.1.1.9
	netbsd-9-1-RELEASE:1.1.1.8
	phil-wifi-20200421:1.1.1.9
	phil-wifi-20200411:1.1.1.9
	phil-wifi-20200406:1.1.1.9
	netbsd-8-2-RELEASE:1.1.1.7
	netbsd-9-0-RELEASE:1.1.1.8
	netbsd-9-0-RC2:1.1.1.8
	netbsd-9-0-RC1:1.1.1.8
	netbsd-9:1.1.1.8.0.6
	netbsd-9-base:1.1.1.8
	phil-wifi-20190609:1.1.1.8
	netbsd-8-1-RELEASE:1.1.1.7
	netbsd-8-1-RC1:1.1.1.7
	pgoyette-compat-merge-20190127:1.1.1.8
	pgoyette-compat-20190127:1.1.1.8
	pgoyette-compat-20190118:1.1.1.8
	pgoyette-compat-1226:1.1.1.8
	pgoyette-compat-1126:1.1.1.8
	pgoyette-compat-1020:1.1.1.8
	pgoyette-compat-0930:1.1.1.8
	pgoyette-compat-0906:1.1.1.8
	netbsd-7-2-RELEASE:1.1.1.4.2.1
	pgoyette-compat-0728:1.1.1.8
	clang-337282:1.1.1.8
	netbsd-8-0-RELEASE:1.1.1.7
	phil-wifi:1.1.1.8.0.4
	phil-wifi-base:1.1.1.8
	pgoyette-compat-0625:1.1.1.8
	netbsd-8-0-RC2:1.1.1.7
	pgoyette-compat-0521:1.1.1.8
	pgoyette-compat-0502:1.1.1.8
	pgoyette-compat-0422:1.1.1.8
	netbsd-8-0-RC1:1.1.1.7
	pgoyette-compat-0415:1.1.1.8
	pgoyette-compat-0407:1.1.1.8
	pgoyette-compat-0330:1.1.1.8
	pgoyette-compat-0322:1.1.1.8
	pgoyette-compat-0315:1.1.1.8
	netbsd-7-1-2-RELEASE:1.1.1.4.2.1
	pgoyette-compat:1.1.1.8.0.2
	pgoyette-compat-base:1.1.1.8
	netbsd-7-1-1-RELEASE:1.1.1.4.2.1
	clang-319952:1.1.1.8
	matt-nb8-mediatek:1.1.1.7.0.10
	matt-nb8-mediatek-base:1.1.1.7
	clang-309604:1.1.1.8
	perseant-stdc-iso10646:1.1.1.7.0.8
	perseant-stdc-iso10646-base:1.1.1.7
	netbsd-8:1.1.1.7.0.6
	netbsd-8-base:1.1.1.7
	prg-localcount2-base3:1.1.1.7
	prg-localcount2-base2:1.1.1.7
	prg-localcount2-base1:1.1.1.7
	prg-localcount2:1.1.1.7.0.4
	prg-localcount2-base:1.1.1.7
	pgoyette-localcount-20170426:1.1.1.7
	bouyer-socketcan-base1:1.1.1.7
	pgoyette-localcount-20170320:1.1.1.7
	netbsd-7-1:1.1.1.4.2.1.0.6
	netbsd-7-1-RELEASE:1.1.1.4.2.1
	netbsd-7-1-RC2:1.1.1.4.2.1
	clang-294123:1.1.1.7
	netbsd-7-nhusb-base-20170116:1.1.1.4.2.1
	bouyer-socketcan:1.1.1.7.0.2
	bouyer-socketcan-base:1.1.1.7
	clang-291444:1.1.1.7
	pgoyette-localcount-20170107:1.1.1.6
	netbsd-7-1-RC1:1.1.1.4.2.1
	pgoyette-localcount-20161104:1.1.1.6
	netbsd-7-0-2-RELEASE:1.1.1.4.2.1
	localcount-20160914:1.1.1.6
	netbsd-7-nhusb:1.1.1.4.2.1.0.4
	netbsd-7-nhusb-base:1.1.1.4.2.1
	clang-280599:1.1.1.6
	pgoyette-localcount-20160806:1.1.1.6
	pgoyette-localcount-20160726:1.1.1.6
	pgoyette-localcount:1.1.1.6.0.2
	pgoyette-localcount-base:1.1.1.6
	netbsd-7-0-1-RELEASE:1.1.1.4.2.1
	clang-261930:1.1.1.6
	netbsd-7-0:1.1.1.4.2.1.0.2
	netbsd-7-0-RELEASE:1.1.1.4.2.1
	netbsd-7-0-RC3:1.1.1.4.2.1
	netbsd-7-0-RC2:1.1.1.4.2.1
	netbsd-7-0-RC1:1.1.1.4.2.1
	clang-237755:1.1.1.5
	clang-232565:1.1.1.5
	clang-227398:1.1.1.5
	tls-maxphys-base:1.1.1.4
	tls-maxphys:1.1.1.4.0.4
	netbsd-7:1.1.1.4.0.2
	netbsd-7-base:1.1.1.4
	clang-215315:1.1.1.4
	clang-209886:1.1.1.3
	yamt-pagecache:1.1.1.2.0.4
	yamt-pagecache-base9:1.1.1.2
	tls-earlyentropy:1.1.1.2.0.2
	tls-earlyentropy-base:1.1.1.3
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.1.1.2
	riastradh-drm2-base3:1.1.1.2
	clang-202566:1.1.1.2
	clang-201163:1.1.1.1
	clang-199312:1.1.1.1
	clang-198450:1.1.1.1
	clang-196603:1.1.1.1
	clang-195771:1.1.1.1
	LLVM:1.1.1;
locks; strict;
comment	@// @;


1.1
date	2013.11.28.14.14.49;	author joerg;	state Exp;
branches
	1.1.1.1;
next	;
commitid	ow8OybrawrB1f3fx;

1.1.1.1
date	2013.11.28.14.14.49;	author joerg;	state Exp;
branches;
next	1.1.1.2;
commitid	ow8OybrawrB1f3fx;

1.1.1.2
date	2014.03.04.19.53.44;	author joerg;	state Exp;
branches
	1.1.1.2.2.1
	1.1.1.2.4.1;
next	1.1.1.3;
commitid	29z1hJonZISIXprx;

1.1.1.3
date	2014.05.30.18.14.41;	author joerg;	state Exp;
branches;
next	1.1.1.4;
commitid	8q0kdlBlCn09GACx;

1.1.1.4
date	2014.08.10.17.08.27;	author joerg;	state Exp;
branches
	1.1.1.4.2.1
	1.1.1.4.4.1;
next	1.1.1.5;
commitid	N85tXAN6Ex9VZPLx;

1.1.1.5
date	2015.01.29.19.57.32;	author joerg;	state Exp;
branches;
next	1.1.1.6;
commitid	mlISSizlPKvepX7y;

1.1.1.6
date	2016.02.27.22.11.52;	author joerg;	state Exp;
branches
	1.1.1.6.2.1;
next	1.1.1.7;
commitid	tIimz3oDlh1NpBWy;

1.1.1.7
date	2017.01.11.10.34.48;	author joerg;	state Exp;
branches;
next	1.1.1.8;
commitid	CNnUNfII1jgNmxBz;

1.1.1.8
date	2017.08.01.19.34.54;	author joerg;	state Exp;
branches
	1.1.1.8.4.1;
next	1.1.1.9;
commitid	pMuDy65V0VicSx1A;

1.1.1.9
date	2019.11.13.22.19.23;	author joerg;	state dead;
branches;
next	;
commitid	QD8YATxuNG34YJKB;

1.1.1.2.2.1
date	2014.08.10.07.08.08;	author tls;	state Exp;
branches;
next	;
commitid	t01A1TLTYxkpGMLx;

1.1.1.2.4.1
date	2014.03.04.19.53.44;	author yamt;	state dead;
branches;
next	1.1.1.2.4.2;
commitid	WSrDtL5nYAUyiyBx;

1.1.1.2.4.2
date	2014.05.22.16.18.27;	author yamt;	state Exp;
branches;
next	;
commitid	WSrDtL5nYAUyiyBx;

1.1.1.4.2.1
date	2015.06.04.20.04.28;	author snj;	state Exp;
branches;
next	;
commitid	yRnjq9fueSo6n9oy;

1.1.1.4.4.1
date	2014.08.10.17.08.27;	author tls;	state dead;
branches;
next	1.1.1.4.4.2;
commitid	jTnpym9Qu0o4R1Nx;

1.1.1.4.4.2
date	2014.08.19.23.47.28;	author tls;	state Exp;
branches;
next	;
commitid	jTnpym9Qu0o4R1Nx;

1.1.1.6.2.1
date	2017.03.20.06.52.38;	author pgoyette;	state Exp;
branches;
next	;
commitid	jjw7cAwgyKq7RfKz;

1.1.1.8.4.1
date	2020.04.13.07.46.34;	author martin;	state dead;
branches;
next	;
commitid	X01YhRUPVUDaec4C;


desc
@@


1.1
log
@Initial revision
@
text
@//===- ChainedIncludesSource.cpp - Chained PCHs in Memory -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the ChainedIncludesSource class, which converts headers
//  to chained PCHs in memory, mainly used for testing.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/ChainedIncludesSource.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/Support/MemoryBuffer.h"

using namespace clang;

static ASTReader *createASTReader(CompilerInstance &CI,
                             StringRef pchFile,
                             SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
                             SmallVectorImpl<std::string> &bufNames,
                             ASTDeserializationListener *deserialListener = 0) {
  Preprocessor &PP = CI.getPreprocessor();
  OwningPtr<ASTReader> Reader;
  Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"",
                             /*DisableValidation=*/true));
  for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
    StringRef sr(bufNames[ti]);
    Reader->addInMemoryBuffer(sr, memBufs[ti]);
  }
  Reader->setDeserializationListener(deserialListener);
  switch (Reader->ReadAST(pchFile, serialization::MK_PCH, SourceLocation(),
                          ASTReader::ARR_None)) {
  case ASTReader::Success:
    // Set the predefines buffer as suggested by the PCH reader.
    PP.setPredefines(Reader->getSuggestedPredefines());
    return Reader.take();

  case ASTReader::Failure:
  case ASTReader::Missing:
  case ASTReader::OutOfDate:
  case ASTReader::VersionMismatch:
  case ASTReader::ConfigurationMismatch:
  case ASTReader::HadErrors:
    break;
  }
  return 0;
}

ChainedIncludesSource::~ChainedIncludesSource() {
  for (unsigned i = 0, e = CIs.size(); i != e; ++i)
    delete CIs[i];
}

ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) {

  std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes;
  assert(!includes.empty() && "No '-chain-include' in options!");

  OwningPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
  InputKind IK = CI.getFrontendOpts().Inputs[0].getKind();

  SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
  SmallVector<std::string, 4> serialBufNames;

  for (unsigned i = 0, e = includes.size(); i != e; ++i) {
    bool firstInclude = (i == 0);
    OwningPtr<CompilerInvocation> CInvok;
    CInvok.reset(new CompilerInvocation(CI.getInvocation()));
    
    CInvok->getPreprocessorOpts().ChainedIncludes.clear();
    CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
    CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear();
    CInvok->getPreprocessorOpts().DisablePCHValidation = true;
    CInvok->getPreprocessorOpts().Includes.clear();
    CInvok->getPreprocessorOpts().MacroIncludes.clear();
    CInvok->getPreprocessorOpts().Macros.clear();
    
    CInvok->getFrontendOpts().Inputs.clear();
    FrontendInputFile InputFile(includes[i], IK);
    CInvok->getFrontendOpts().Inputs.push_back(InputFile);

    TextDiagnosticPrinter *DiagClient =
      new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
    IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
        new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient));

    OwningPtr<CompilerInstance> Clang(new CompilerInstance());
    Clang->setInvocation(CInvok.take());
    Clang->setDiagnostics(Diags.getPtr());
    Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
                                                  &Clang->getTargetOpts()));
    Clang->createFileManager();
    Clang->createSourceManager(Clang->getFileManager());
    Clang->createPreprocessor();
    Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
                                                 &Clang->getPreprocessor());
    Clang->createASTContext();

    SmallVector<char, 256> serialAST;
    llvm::raw_svector_ostream OS(serialAST);
    OwningPtr<ASTConsumer> consumer;
    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", 0,
                                    /*isysroot=*/"", &OS));
    Clang->getASTContext().setASTMutationListener(
                                            consumer->GetASTMutationListener());
    Clang->setASTConsumer(consumer.take());
    Clang->createSema(TU_Prefix, 0);

    if (firstInclude) {
      Preprocessor &PP = Clang->getPreprocessor();
      PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                             PP.getLangOpts());
    } else {
      assert(!serialBufs.empty());
      SmallVector<llvm::MemoryBuffer *, 4> bufs;
      for (unsigned si = 0, se = serialBufs.size(); si != se; ++si) {
        bufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
                             StringRef(serialBufs[si]->getBufferStart(),
                                             serialBufs[si]->getBufferSize())));
      }
      std::string pchName = includes[i-1];
      llvm::raw_string_ostream os(pchName);
      os << ".pch" << i-1;
      os.flush();
      
      serialBufNames.push_back(pchName);

      OwningPtr<ExternalASTSource> Reader;

      Reader.reset(createASTReader(*Clang, pchName, bufs, serialBufNames, 
        Clang->getASTConsumer().GetASTDeserializationListener()));
      if (!Reader)
        return 0;
      Clang->setModuleManager(static_cast<ASTReader*>(Reader.get()));
      Clang->getASTContext().setExternalSource(Reader);
    }
    
    if (!Clang->InitializeSourceManager(InputFile))
      return 0;

    ParseAST(Clang->getSema());
    OS.flush();
    Clang->getDiagnosticClient().EndSourceFile();
    serialBufs.push_back(
      llvm::MemoryBuffer::getMemBufferCopy(StringRef(serialAST.data(),
                                                           serialAST.size())));
    source->CIs.push_back(Clang.take());
  }

  assert(!serialBufs.empty());
  std::string pchName = includes.back() + ".pch-final";
  serialBufNames.push_back(pchName);
  OwningPtr<ASTReader> Reader;
  Reader.reset(createASTReader(CI, pchName, serialBufs, serialBufNames));
  if (!Reader)
    return 0;

  source->FinalReader.reset(Reader.take());
  return source.take();
}

//===----------------------------------------------------------------------===//
// ExternalASTSource interface.
//===----------------------------------------------------------------------===//

Decl *ChainedIncludesSource::GetExternalDecl(uint32_t ID) {
  return getFinalReader().GetExternalDecl(ID);
}
Selector ChainedIncludesSource::GetExternalSelector(uint32_t ID) {
  return getFinalReader().GetExternalSelector(ID);
}
uint32_t ChainedIncludesSource::GetNumExternalSelectors() {
  return getFinalReader().GetNumExternalSelectors();
}
Stmt *ChainedIncludesSource::GetExternalDeclStmt(uint64_t Offset) {
  return getFinalReader().GetExternalDeclStmt(Offset);
}
CXXBaseSpecifier *
ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
  return getFinalReader().GetExternalCXXBaseSpecifiers(Offset);
}
bool
ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
                                                      DeclarationName Name) {
  return getFinalReader().FindExternalVisibleDeclsByName(DC, Name);
}
ExternalLoadResult 
ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC,
                                      bool (*isKindWeWant)(Decl::Kind),
                                      SmallVectorImpl<Decl*> &Result) {
  return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);
}
void ChainedIncludesSource::CompleteType(TagDecl *Tag) {
  return getFinalReader().CompleteType(Tag);
}
void ChainedIncludesSource::CompleteType(ObjCInterfaceDecl *Class) {
  return getFinalReader().CompleteType(Class);
}
void ChainedIncludesSource::StartedDeserializing() {
  return getFinalReader().StartedDeserializing();
}
void ChainedIncludesSource::FinishedDeserializing() {
  return getFinalReader().FinishedDeserializing();
}
void ChainedIncludesSource::StartTranslationUnit(ASTConsumer *Consumer) {
  return getFinalReader().StartTranslationUnit(Consumer);
}
void ChainedIncludesSource::PrintStats() {
  return getFinalReader().PrintStats();
}
void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)const{
  for (unsigned i = 0, e = CIs.size(); i != e; ++i) {
    if (const ExternalASTSource *eSrc =
        CIs[i]->getASTContext().getExternalSource()) {
      eSrc->getMemoryBufferSizes(sizes);
    }
  }

  getFinalReader().getMemoryBufferSizes(sizes);
}

void ChainedIncludesSource::InitializeSema(Sema &S) {
  return getFinalReader().InitializeSema(S);
}
void ChainedIncludesSource::ForgetSema() {
  return getFinalReader().ForgetSema();
}
void ChainedIncludesSource::ReadMethodPool(Selector Sel) {
  getFinalReader().ReadMethodPool(Sel);
}
bool ChainedIncludesSource::LookupUnqualified(LookupResult &R, Scope *S) {
  return getFinalReader().LookupUnqualified(R, S);
}

@


1.1.1.1
log
@Import Clang 3.4rc1 r195771.
@
text
@@


1.1.1.2
log
@Import Clang 3.5svn r202566.
@
text
@d65 1
a65 2
IntrusiveRefCntPtr<ChainedIncludesSource>
ChainedIncludesSource::create(CompilerInstance &CI) {
d70 1
a70 1
  IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
d140 4
a143 3
      IntrusiveRefCntPtr<ASTReader> Reader;
      Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, 
        Clang->getASTConsumer().GetASTDeserializationListener());
d146 1
a146 1
      Clang->setModuleManager(Reader);
d165 2
a166 2
  IntrusiveRefCntPtr<ASTReader> Reader;
  Reader = createASTReader(CI, pchName, serialBufs, serialBufNames);
d170 2
a171 2
  source->FinalReader = Reader;
  return source;
@


1.1.1.2.2.1
log
@Rebase.
@
text
@d28 5
a32 5
static ASTReader *
createASTReader(CompilerInstance &CI, StringRef pchFile,
                SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
                SmallVectorImpl<std::string> &bufNames,
                ASTDeserializationListener *deserialListener = nullptr) {
d34 1
a34 1
  std::unique_ptr<ASTReader> Reader;
d47 1
a47 1
    return Reader.release();
d57 1
a57 1
  return nullptr;
d79 1
a79 1
    std::unique_ptr<CompilerInvocation> CInvok;
d100 2
a101 2
    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
    Clang->setInvocation(CInvok.release());
d107 1
a107 1
    Clang->createPreprocessor(TU_Prefix);
d114 2
a115 2
    std::unique_ptr<ASTConsumer> consumer;
    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", nullptr,
d119 2
a120 2
    Clang->setASTConsumer(consumer.release());
    Clang->createSema(TU_Prefix, nullptr);
d145 1
a145 1
        return nullptr;
d151 1
a151 1
      return nullptr;
d159 1
a159 1
    source->CIs.push_back(Clang.release());
d168 1
a168 1
    return nullptr;
@


1.1.1.3
log
@Import Clang 3.5svn r209886.
@
text
@d28 5
a32 5
static ASTReader *
createASTReader(CompilerInstance &CI, StringRef pchFile,
                SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
                SmallVectorImpl<std::string> &bufNames,
                ASTDeserializationListener *deserialListener = nullptr) {
d34 1
a34 1
  std::unique_ptr<ASTReader> Reader;
d47 1
a47 1
    return Reader.release();
d57 1
a57 1
  return nullptr;
d79 1
a79 1
    std::unique_ptr<CompilerInvocation> CInvok;
d100 2
a101 2
    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
    Clang->setInvocation(CInvok.release());
d107 1
a107 1
    Clang->createPreprocessor(TU_Prefix);
d114 2
a115 2
    std::unique_ptr<ASTConsumer> consumer;
    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", nullptr,
d119 2
a120 2
    Clang->setASTConsumer(consumer.release());
    Clang->createSema(TU_Prefix, nullptr);
d145 1
a145 1
        return nullptr;
d151 1
a151 1
      return nullptr;
d159 1
a159 1
    source->CIs.push_back(Clang.release());
d168 1
a168 1
    return nullptr;
@


1.1.1.4
log
@Import clang 3.6svn r215315.
@
text
@d15 1
a27 48
namespace {
class ChainedIncludesSource : public ExternalSemaSource {
public:
  virtual ~ChainedIncludesSource();

  ExternalSemaSource &getFinalReader() const { return *FinalReader; }

  std::vector<CompilerInstance *> CIs;
  IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;

protected:
  //===----------------------------------------------------------------------===//
  // ExternalASTSource interface.
  //===----------------------------------------------------------------------===//

  Decl *GetExternalDecl(uint32_t ID) override;
  Selector GetExternalSelector(uint32_t ID) override;
  uint32_t GetNumExternalSelectors() override;
  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
                                      DeclarationName Name) override;
  ExternalLoadResult
  FindExternalLexicalDecls(const DeclContext *DC,
                           bool (*isKindWeWant)(Decl::Kind),
                           SmallVectorImpl<Decl *> &Result) override;
  void CompleteType(TagDecl *Tag) override;
  void CompleteType(ObjCInterfaceDecl *Class) override;
  void StartedDeserializing() override;
  void FinishedDeserializing() override;
  void StartTranslationUnit(ASTConsumer *Consumer) override;
  void PrintStats() override;

  /// Return the amount of memory used by memory buffers, breaking down
  /// by heap-backed versus mmap'ed memory.
  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;

  //===----------------------------------------------------------------------===//
  // ExternalSemaSource interface.
  //===----------------------------------------------------------------------===//

  void InitializeSema(Sema &S) override;
  void ForgetSema() override;
  void ReadMethodPool(Selector Sel) override;
  bool LookupUnqualified(LookupResult &R, Scope *S) override;
};
}

d65 2
a66 2
IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
    CompilerInstance &CI, IntrusiveRefCntPtr<ExternalSemaSource> &Reader) {
d102 3
a104 3
    Clang->setDiagnostics(Diags.get());
    Clang->setTarget(TargetInfo::CreateTargetInfo(
        Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
d129 5
a133 4
      // TODO: Pass through the existing MemoryBuffer instances instead of
      // allocating new ones.
      for (auto *SB : serialBufs)
        bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
d137 3
a139 1
      serialBufNames.push_back(os.str());
d154 1
d156 3
a158 1
    serialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
d165 1
@


1.1.1.4.2.1
log
@Update LLVM to 3.6.1, requested by joerg in ticket 824.
@
text
@d77 1
a77 1
                SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &MemBufs,
d86 1
a86 1
    Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
d121 1
a121 1
  SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> SerialBufs;
d161 3
a163 3
    auto consumer =
        llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr,
                                        /*isysroot=*/"", &OS);
d166 1
a166 1
    Clang->setASTConsumer(std::move(consumer));
d174 2
a175 2
      assert(!SerialBufs.empty());
      SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> Bufs;
d178 2
a179 2
      for (auto &SB : SerialBufs)
        Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
d186 2
a187 3
      Reader = createASTReader(
          *Clang, pchName, Bufs, serialBufNames,
          Clang->getASTConsumer().GetASTDeserializationListener());
d199 1
a199 1
    SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
d203 1
a203 1
  assert(!SerialBufs.empty());
d206 1
a206 1
  Reader = createASTReader(CI, pchName, SerialBufs, serialBufNames);
@


1.1.1.5
log
@Import Clang 3.6RC1 r227398.
@
text
@d77 1
a77 1
                SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &MemBufs,
d86 1
a86 1
    Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
d121 1
a121 1
  SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> SerialBufs;
d161 3
a163 3
    auto consumer =
        llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr,
                                        /*isysroot=*/"", &OS);
d166 1
a166 1
    Clang->setASTConsumer(std::move(consumer));
d174 2
a175 2
      assert(!SerialBufs.empty());
      SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> Bufs;
d178 2
a179 2
      for (auto &SB : SerialBufs)
        Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
d186 2
a187 3
      Reader = createASTReader(
          *Clang, pchName, Bufs, serialBufNames,
          Clang->getASTConsumer().GetASTDeserializationListener());
d199 1
a199 1
    SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
d203 1
a203 1
  assert(!SerialBufs.empty());
d206 1
a206 1
  Reader = createASTReader(CI, pchName, SerialBufs, serialBufNames);
@


1.1.1.6
log
@Import Clang 3.8.0rc3 r261930.
@
text
@d30 1
a30 1
  ~ChainedIncludesSource() override;
a45 1
  CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override;
d49 1
a49 1
  void
d51 1
a51 1
                           llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
d82 2
a83 4
  Reader.reset(new ASTReader(PP, CI.getASTContext(),
                             CI.getPCHContainerReader(),
                             /*Extensions=*/{ },
                             /*isysroot=*/"", /*DisableValidation=*/true));
d147 1
a147 2
    std::unique_ptr<CompilerInstance> Clang(
        new CompilerInstance(CI.getPCHContainerOperations()));
d159 5
a163 5
    auto Buffer = std::make_shared<PCHBuffer>();
    ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions;
    auto consumer = llvm::make_unique<PCHGenerator>(
        Clang->getPreprocessor(), "-", nullptr, /*isysroot=*/"", Buffer,
        Extensions);
d171 1
a171 1
      PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
d200 1
a200 5
    assert(Buffer->IsComplete && "serialization did not complete");
    auto &serialAST = Buffer->Data;
    SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
        StringRef(serialAST.data(), serialAST.size())));
    serialAST.clear();
a234 4
CXXCtorInitializer **
ChainedIncludesSource::GetExternalCXXCtorInitializers(uint64_t Offset) {
  return getFinalReader().GetExternalCXXCtorInitializers(Offset);
}
d240 5
a244 4
void ChainedIncludesSource::FindExternalLexicalDecls(
    const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
    SmallVectorImpl<Decl *> &Result) {
  return getFinalReader().FindExternalLexicalDecls(DC, IsKindWeWant, Result);
@


1.1.1.6.2.1
log
@Sync with HEAD
@
text
@a19 1
#include "clang/Lex/PreprocessorOptions.h"
a20 1
#include "clang/Sema/MultiplexExternalSemaSource.h"
d28 1
a28 1
class ChainedIncludesSourceImpl : public ExternalSemaSource {
d30 6
a35 2
  ChainedIncludesSourceImpl(std::vector<std::unique_ptr<CompilerInstance>> CIs)
      : CIs(std::move(CIs)) {}
d42 19
d63 1
a63 8
  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override {
    for (unsigned i = 0, e = CIs.size(); i != e; ++i) {
      if (const ExternalASTSource *eSrc =
          CIs[i]->getASTContext().getExternalSource()) {
        eSrc->getMemoryBufferSizes(sizes);
      }
    }
  }
d65 3
a67 3
private:
  std::vector<std::unique_ptr<CompilerInstance>> CIs;
};
d69 4
a72 21
/// Members of ChainedIncludesSource, factored out so we can initialize
/// them before we initialize the ExternalSemaSource base class.
struct ChainedIncludesSourceMembers {
  ChainedIncludesSourceMembers(
      std::vector<std::unique_ptr<CompilerInstance>> CIs,
      IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
      : Impl(std::move(CIs)), FinalReader(std::move(FinalReader)) {}
  ChainedIncludesSourceImpl Impl;
  IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
};

/// Use MultiplexExternalSemaSource to dispatch all ExternalSemaSource
/// calls to the final reader.
class ChainedIncludesSource
    : private ChainedIncludesSourceMembers,
      public MultiplexExternalSemaSource {
public:
  ChainedIncludesSource(std::vector<std::unique_ptr<CompilerInstance>> CIs,
                        IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
      : ChainedIncludesSourceMembers(std::move(CIs), std::move(FinalReader)),
        MultiplexExternalSemaSource(Impl, *this->FinalReader) {}
d110 5
d121 1
a121 1
  std::vector<std::unique_ptr<CompilerInstance>> CIs;
d152 1
a152 1
    Clang->setInvocation(std::move(CInvok));
d164 1
a164 1
    ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions;
d166 2
a167 2
        Clang->getPreprocessor(), "-", /*isysroot=*/"", Buffer,
        Extensions, /*AllowASTWithErrors=*/true);
d209 1
a209 1
    CIs.push_back(std::move(Clang));
d219 19
a237 2
  return IntrusiveRefCntPtr<ChainedIncludesSource>(
      new ChainedIncludesSource(std::move(CIs), Reader));
d239 60
@


1.1.1.7
log
@Import Clang pre-4.0.0 r291444.
@
text
@a19 1
#include "clang/Lex/PreprocessorOptions.h"
a20 1
#include "clang/Sema/MultiplexExternalSemaSource.h"
d28 1
a28 1
class ChainedIncludesSourceImpl : public ExternalSemaSource {
d30 6
a35 2
  ChainedIncludesSourceImpl(std::vector<std::unique_ptr<CompilerInstance>> CIs)
      : CIs(std::move(CIs)) {}
d42 19
d63 1
a63 8
  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override {
    for (unsigned i = 0, e = CIs.size(); i != e; ++i) {
      if (const ExternalASTSource *eSrc =
          CIs[i]->getASTContext().getExternalSource()) {
        eSrc->getMemoryBufferSizes(sizes);
      }
    }
  }
d65 3
a67 3
private:
  std::vector<std::unique_ptr<CompilerInstance>> CIs;
};
d69 4
a72 21
/// Members of ChainedIncludesSource, factored out so we can initialize
/// them before we initialize the ExternalSemaSource base class.
struct ChainedIncludesSourceMembers {
  ChainedIncludesSourceMembers(
      std::vector<std::unique_ptr<CompilerInstance>> CIs,
      IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
      : Impl(std::move(CIs)), FinalReader(std::move(FinalReader)) {}
  ChainedIncludesSourceImpl Impl;
  IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
};

/// Use MultiplexExternalSemaSource to dispatch all ExternalSemaSource
/// calls to the final reader.
class ChainedIncludesSource
    : private ChainedIncludesSourceMembers,
      public MultiplexExternalSemaSource {
public:
  ChainedIncludesSource(std::vector<std::unique_ptr<CompilerInstance>> CIs,
                        IntrusiveRefCntPtr<ExternalSemaSource> FinalReader)
      : ChainedIncludesSourceMembers(std::move(CIs), std::move(FinalReader)),
        MultiplexExternalSemaSource(Impl, *this->FinalReader) {}
d110 5
d121 1
a121 1
  std::vector<std::unique_ptr<CompilerInstance>> CIs;
d152 1
a152 1
    Clang->setInvocation(std::move(CInvok));
d164 1
a164 1
    ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions;
d166 2
a167 2
        Clang->getPreprocessor(), "-", /*isysroot=*/"", Buffer,
        Extensions, /*AllowASTWithErrors=*/true);
d209 1
a209 1
    CIs.push_back(std::move(Clang));
d219 19
a237 2
  return IntrusiveRefCntPtr<ChainedIncludesSource>(
      new ChainedIncludesSource(std::move(CIs), Reader));
d239 60
@


1.1.1.8
log
@Import clang r309604 from branches/release_50
@
text
@d86 1
a86 1
  Reader.reset(new ASTReader(PP, &CI.getASTContext(),
@


1.1.1.8.4.1
log
@Mostly merge changes from HEAD upto 20200411
@
text
@@


1.1.1.9
log
@Mark old LLVM instance as dead.
@
text
@@


1.1.1.4.4.1
log
@file ChainedIncludesSource.cpp was added on branch tls-maxphys on 2014-08-19 23:47:28 +0000
@
text
@d1 286
@


1.1.1.4.4.2
log
@Rebase to HEAD as of a few days ago.
@
text
@a0 286
//===- ChainedIncludesSource.cpp - Chained PCHs in Memory -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the ChainedIncludesSource class, which converts headers
//  to chained PCHs in memory, mainly used for testing.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/Support/MemoryBuffer.h"

using namespace clang;

namespace {
class ChainedIncludesSource : public ExternalSemaSource {
public:
  virtual ~ChainedIncludesSource();

  ExternalSemaSource &getFinalReader() const { return *FinalReader; }

  std::vector<CompilerInstance *> CIs;
  IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;

protected:
  //===----------------------------------------------------------------------===//
  // ExternalASTSource interface.
  //===----------------------------------------------------------------------===//

  Decl *GetExternalDecl(uint32_t ID) override;
  Selector GetExternalSelector(uint32_t ID) override;
  uint32_t GetNumExternalSelectors() override;
  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
                                      DeclarationName Name) override;
  ExternalLoadResult
  FindExternalLexicalDecls(const DeclContext *DC,
                           bool (*isKindWeWant)(Decl::Kind),
                           SmallVectorImpl<Decl *> &Result) override;
  void CompleteType(TagDecl *Tag) override;
  void CompleteType(ObjCInterfaceDecl *Class) override;
  void StartedDeserializing() override;
  void FinishedDeserializing() override;
  void StartTranslationUnit(ASTConsumer *Consumer) override;
  void PrintStats() override;

  /// Return the amount of memory used by memory buffers, breaking down
  /// by heap-backed versus mmap'ed memory.
  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;

  //===----------------------------------------------------------------------===//
  // ExternalSemaSource interface.
  //===----------------------------------------------------------------------===//

  void InitializeSema(Sema &S) override;
  void ForgetSema() override;
  void ReadMethodPool(Selector Sel) override;
  bool LookupUnqualified(LookupResult &R, Scope *S) override;
};
}

static ASTReader *
createASTReader(CompilerInstance &CI, StringRef pchFile,
                SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
                SmallVectorImpl<std::string> &bufNames,
                ASTDeserializationListener *deserialListener = nullptr) {
  Preprocessor &PP = CI.getPreprocessor();
  std::unique_ptr<ASTReader> Reader;
  Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"",
                             /*DisableValidation=*/true));
  for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
    StringRef sr(bufNames[ti]);
    Reader->addInMemoryBuffer(sr, memBufs[ti]);
  }
  Reader->setDeserializationListener(deserialListener);
  switch (Reader->ReadAST(pchFile, serialization::MK_PCH, SourceLocation(),
                          ASTReader::ARR_None)) {
  case ASTReader::Success:
    // Set the predefines buffer as suggested by the PCH reader.
    PP.setPredefines(Reader->getSuggestedPredefines());
    return Reader.release();

  case ASTReader::Failure:
  case ASTReader::Missing:
  case ASTReader::OutOfDate:
  case ASTReader::VersionMismatch:
  case ASTReader::ConfigurationMismatch:
  case ASTReader::HadErrors:
    break;
  }
  return nullptr;
}

ChainedIncludesSource::~ChainedIncludesSource() {
  for (unsigned i = 0, e = CIs.size(); i != e; ++i)
    delete CIs[i];
}

IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
    CompilerInstance &CI, IntrusiveRefCntPtr<ExternalSemaSource> &Reader) {

  std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes;
  assert(!includes.empty() && "No '-chain-include' in options!");

  IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
  InputKind IK = CI.getFrontendOpts().Inputs[0].getKind();

  SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
  SmallVector<std::string, 4> serialBufNames;

  for (unsigned i = 0, e = includes.size(); i != e; ++i) {
    bool firstInclude = (i == 0);
    std::unique_ptr<CompilerInvocation> CInvok;
    CInvok.reset(new CompilerInvocation(CI.getInvocation()));
    
    CInvok->getPreprocessorOpts().ChainedIncludes.clear();
    CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
    CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear();
    CInvok->getPreprocessorOpts().DisablePCHValidation = true;
    CInvok->getPreprocessorOpts().Includes.clear();
    CInvok->getPreprocessorOpts().MacroIncludes.clear();
    CInvok->getPreprocessorOpts().Macros.clear();
    
    CInvok->getFrontendOpts().Inputs.clear();
    FrontendInputFile InputFile(includes[i], IK);
    CInvok->getFrontendOpts().Inputs.push_back(InputFile);

    TextDiagnosticPrinter *DiagClient =
      new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
    IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
        new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient));

    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
    Clang->setInvocation(CInvok.release());
    Clang->setDiagnostics(Diags.get());
    Clang->setTarget(TargetInfo::CreateTargetInfo(
        Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
    Clang->createFileManager();
    Clang->createSourceManager(Clang->getFileManager());
    Clang->createPreprocessor(TU_Prefix);
    Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
                                                 &Clang->getPreprocessor());
    Clang->createASTContext();

    SmallVector<char, 256> serialAST;
    llvm::raw_svector_ostream OS(serialAST);
    std::unique_ptr<ASTConsumer> consumer;
    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", nullptr,
                                    /*isysroot=*/"", &OS));
    Clang->getASTContext().setASTMutationListener(
                                            consumer->GetASTMutationListener());
    Clang->setASTConsumer(consumer.release());
    Clang->createSema(TU_Prefix, nullptr);

    if (firstInclude) {
      Preprocessor &PP = Clang->getPreprocessor();
      PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                             PP.getLangOpts());
    } else {
      assert(!serialBufs.empty());
      SmallVector<llvm::MemoryBuffer *, 4> bufs;
      // TODO: Pass through the existing MemoryBuffer instances instead of
      // allocating new ones.
      for (auto *SB : serialBufs)
        bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
      std::string pchName = includes[i-1];
      llvm::raw_string_ostream os(pchName);
      os << ".pch" << i-1;
      serialBufNames.push_back(os.str());

      IntrusiveRefCntPtr<ASTReader> Reader;
      Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, 
        Clang->getASTConsumer().GetASTDeserializationListener());
      if (!Reader)
        return nullptr;
      Clang->setModuleManager(Reader);
      Clang->getASTContext().setExternalSource(Reader);
    }
    
    if (!Clang->InitializeSourceManager(InputFile))
      return nullptr;

    ParseAST(Clang->getSema());
    Clang->getDiagnosticClient().EndSourceFile();
    serialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
    source->CIs.push_back(Clang.release());
  }

  assert(!serialBufs.empty());
  std::string pchName = includes.back() + ".pch-final";
  serialBufNames.push_back(pchName);
  Reader = createASTReader(CI, pchName, serialBufs, serialBufNames);
  if (!Reader)
    return nullptr;

  source->FinalReader = Reader;
  return source;
}

//===----------------------------------------------------------------------===//
// ExternalASTSource interface.
//===----------------------------------------------------------------------===//

Decl *ChainedIncludesSource::GetExternalDecl(uint32_t ID) {
  return getFinalReader().GetExternalDecl(ID);
}
Selector ChainedIncludesSource::GetExternalSelector(uint32_t ID) {
  return getFinalReader().GetExternalSelector(ID);
}
uint32_t ChainedIncludesSource::GetNumExternalSelectors() {
  return getFinalReader().GetNumExternalSelectors();
}
Stmt *ChainedIncludesSource::GetExternalDeclStmt(uint64_t Offset) {
  return getFinalReader().GetExternalDeclStmt(Offset);
}
CXXBaseSpecifier *
ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
  return getFinalReader().GetExternalCXXBaseSpecifiers(Offset);
}
bool
ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
                                                      DeclarationName Name) {
  return getFinalReader().FindExternalVisibleDeclsByName(DC, Name);
}
ExternalLoadResult 
ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC,
                                      bool (*isKindWeWant)(Decl::Kind),
                                      SmallVectorImpl<Decl*> &Result) {
  return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);
}
void ChainedIncludesSource::CompleteType(TagDecl *Tag) {
  return getFinalReader().CompleteType(Tag);
}
void ChainedIncludesSource::CompleteType(ObjCInterfaceDecl *Class) {
  return getFinalReader().CompleteType(Class);
}
void ChainedIncludesSource::StartedDeserializing() {
  return getFinalReader().StartedDeserializing();
}
void ChainedIncludesSource::FinishedDeserializing() {
  return getFinalReader().FinishedDeserializing();
}
void ChainedIncludesSource::StartTranslationUnit(ASTConsumer *Consumer) {
  return getFinalReader().StartTranslationUnit(Consumer);
}
void ChainedIncludesSource::PrintStats() {
  return getFinalReader().PrintStats();
}
void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)const{
  for (unsigned i = 0, e = CIs.size(); i != e; ++i) {
    if (const ExternalASTSource *eSrc =
        CIs[i]->getASTContext().getExternalSource()) {
      eSrc->getMemoryBufferSizes(sizes);
    }
  }

  getFinalReader().getMemoryBufferSizes(sizes);
}

void ChainedIncludesSource::InitializeSema(Sema &S) {
  return getFinalReader().InitializeSema(S);
}
void ChainedIncludesSource::ForgetSema() {
  return getFinalReader().ForgetSema();
}
void ChainedIncludesSource::ReadMethodPool(Selector Sel) {
  getFinalReader().ReadMethodPool(Sel);
}
bool ChainedIncludesSource::LookupUnqualified(LookupResult &R, Scope *S) {
  return getFinalReader().LookupUnqualified(R, S);
}

@


1.1.1.2.4.1
log
@file ChainedIncludesSource.cpp was added on branch yamt-pagecache on 2014-05-22 16:18:27 +0000
@
text
@d1 246
@


1.1.1.2.4.2
log
@sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs.  ("Protocol error: too many arguments")
@
text
@a0 246
//===- ChainedIncludesSource.cpp - Chained PCHs in Memory -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the ChainedIncludesSource class, which converts headers
//  to chained PCHs in memory, mainly used for testing.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/ChainedIncludesSource.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/Support/MemoryBuffer.h"

using namespace clang;

static ASTReader *createASTReader(CompilerInstance &CI,
                             StringRef pchFile,
                             SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
                             SmallVectorImpl<std::string> &bufNames,
                             ASTDeserializationListener *deserialListener = 0) {
  Preprocessor &PP = CI.getPreprocessor();
  OwningPtr<ASTReader> Reader;
  Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"",
                             /*DisableValidation=*/true));
  for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
    StringRef sr(bufNames[ti]);
    Reader->addInMemoryBuffer(sr, memBufs[ti]);
  }
  Reader->setDeserializationListener(deserialListener);
  switch (Reader->ReadAST(pchFile, serialization::MK_PCH, SourceLocation(),
                          ASTReader::ARR_None)) {
  case ASTReader::Success:
    // Set the predefines buffer as suggested by the PCH reader.
    PP.setPredefines(Reader->getSuggestedPredefines());
    return Reader.take();

  case ASTReader::Failure:
  case ASTReader::Missing:
  case ASTReader::OutOfDate:
  case ASTReader::VersionMismatch:
  case ASTReader::ConfigurationMismatch:
  case ASTReader::HadErrors:
    break;
  }
  return 0;
}

ChainedIncludesSource::~ChainedIncludesSource() {
  for (unsigned i = 0, e = CIs.size(); i != e; ++i)
    delete CIs[i];
}

IntrusiveRefCntPtr<ChainedIncludesSource>
ChainedIncludesSource::create(CompilerInstance &CI) {

  std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes;
  assert(!includes.empty() && "No '-chain-include' in options!");

  IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
  InputKind IK = CI.getFrontendOpts().Inputs[0].getKind();

  SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
  SmallVector<std::string, 4> serialBufNames;

  for (unsigned i = 0, e = includes.size(); i != e; ++i) {
    bool firstInclude = (i == 0);
    OwningPtr<CompilerInvocation> CInvok;
    CInvok.reset(new CompilerInvocation(CI.getInvocation()));
    
    CInvok->getPreprocessorOpts().ChainedIncludes.clear();
    CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();
    CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear();
    CInvok->getPreprocessorOpts().DisablePCHValidation = true;
    CInvok->getPreprocessorOpts().Includes.clear();
    CInvok->getPreprocessorOpts().MacroIncludes.clear();
    CInvok->getPreprocessorOpts().Macros.clear();
    
    CInvok->getFrontendOpts().Inputs.clear();
    FrontendInputFile InputFile(includes[i], IK);
    CInvok->getFrontendOpts().Inputs.push_back(InputFile);

    TextDiagnosticPrinter *DiagClient =
      new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
    IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
        new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient));

    OwningPtr<CompilerInstance> Clang(new CompilerInstance());
    Clang->setInvocation(CInvok.take());
    Clang->setDiagnostics(Diags.getPtr());
    Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
                                                  &Clang->getTargetOpts()));
    Clang->createFileManager();
    Clang->createSourceManager(Clang->getFileManager());
    Clang->createPreprocessor();
    Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
                                                 &Clang->getPreprocessor());
    Clang->createASTContext();

    SmallVector<char, 256> serialAST;
    llvm::raw_svector_ostream OS(serialAST);
    OwningPtr<ASTConsumer> consumer;
    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", 0,
                                    /*isysroot=*/"", &OS));
    Clang->getASTContext().setASTMutationListener(
                                            consumer->GetASTMutationListener());
    Clang->setASTConsumer(consumer.take());
    Clang->createSema(TU_Prefix, 0);

    if (firstInclude) {
      Preprocessor &PP = Clang->getPreprocessor();
      PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                             PP.getLangOpts());
    } else {
      assert(!serialBufs.empty());
      SmallVector<llvm::MemoryBuffer *, 4> bufs;
      for (unsigned si = 0, se = serialBufs.size(); si != se; ++si) {
        bufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
                             StringRef(serialBufs[si]->getBufferStart(),
                                             serialBufs[si]->getBufferSize())));
      }
      std::string pchName = includes[i-1];
      llvm::raw_string_ostream os(pchName);
      os << ".pch" << i-1;
      os.flush();
      
      serialBufNames.push_back(pchName);

      IntrusiveRefCntPtr<ASTReader> Reader;
      Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, 
        Clang->getASTConsumer().GetASTDeserializationListener());
      if (!Reader)
        return 0;
      Clang->setModuleManager(Reader);
      Clang->getASTContext().setExternalSource(Reader);
    }
    
    if (!Clang->InitializeSourceManager(InputFile))
      return 0;

    ParseAST(Clang->getSema());
    OS.flush();
    Clang->getDiagnosticClient().EndSourceFile();
    serialBufs.push_back(
      llvm::MemoryBuffer::getMemBufferCopy(StringRef(serialAST.data(),
                                                           serialAST.size())));
    source->CIs.push_back(Clang.take());
  }

  assert(!serialBufs.empty());
  std::string pchName = includes.back() + ".pch-final";
  serialBufNames.push_back(pchName);
  IntrusiveRefCntPtr<ASTReader> Reader;
  Reader = createASTReader(CI, pchName, serialBufs, serialBufNames);
  if (!Reader)
    return 0;

  source->FinalReader = Reader;
  return source;
}

//===----------------------------------------------------------------------===//
// ExternalASTSource interface.
//===----------------------------------------------------------------------===//

Decl *ChainedIncludesSource::GetExternalDecl(uint32_t ID) {
  return getFinalReader().GetExternalDecl(ID);
}
Selector ChainedIncludesSource::GetExternalSelector(uint32_t ID) {
  return getFinalReader().GetExternalSelector(ID);
}
uint32_t ChainedIncludesSource::GetNumExternalSelectors() {
  return getFinalReader().GetNumExternalSelectors();
}
Stmt *ChainedIncludesSource::GetExternalDeclStmt(uint64_t Offset) {
  return getFinalReader().GetExternalDeclStmt(Offset);
}
CXXBaseSpecifier *
ChainedIncludesSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
  return getFinalReader().GetExternalCXXBaseSpecifiers(Offset);
}
bool
ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
                                                      DeclarationName Name) {
  return getFinalReader().FindExternalVisibleDeclsByName(DC, Name);
}
ExternalLoadResult 
ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC,
                                      bool (*isKindWeWant)(Decl::Kind),
                                      SmallVectorImpl<Decl*> &Result) {
  return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);
}
void ChainedIncludesSource::CompleteType(TagDecl *Tag) {
  return getFinalReader().CompleteType(Tag);
}
void ChainedIncludesSource::CompleteType(ObjCInterfaceDecl *Class) {
  return getFinalReader().CompleteType(Class);
}
void ChainedIncludesSource::StartedDeserializing() {
  return getFinalReader().StartedDeserializing();
}
void ChainedIncludesSource::FinishedDeserializing() {
  return getFinalReader().FinishedDeserializing();
}
void ChainedIncludesSource::StartTranslationUnit(ASTConsumer *Consumer) {
  return getFinalReader().StartTranslationUnit(Consumer);
}
void ChainedIncludesSource::PrintStats() {
  return getFinalReader().PrintStats();
}
void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)const{
  for (unsigned i = 0, e = CIs.size(); i != e; ++i) {
    if (const ExternalASTSource *eSrc =
        CIs[i]->getASTContext().getExternalSource()) {
      eSrc->getMemoryBufferSizes(sizes);
    }
  }

  getFinalReader().getMemoryBufferSizes(sizes);
}

void ChainedIncludesSource::InitializeSema(Sema &S) {
  return getFinalReader().InitializeSema(S);
}
void ChainedIncludesSource::ForgetSema() {
  return getFinalReader().ForgetSema();
}
void ChainedIncludesSource::ReadMethodPool(Selector Sel) {
  getFinalReader().ReadMethodPool(Sel);
}
bool ChainedIncludesSource::LookupUnqualified(LookupResult &R, Scope *S) {
  return getFinalReader().LookupUnqualified(R, S);
}

@


