r212060 - Consider module depedencies when checking a preamble in libclang
Nico Weber
thakis at chromium.org
Wed Jul 16 09:34:16 PDT 2014
…with this stack:
(lldb) run
Process 23113 launched:
'./tools/clang/unittests/libclang/Debug+Asserts/libclangTests' (x86_64)
Note: Google Test filter = LibclangReparseTest.ReparseWithModule
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from LibclangReparseTest
[ RUN ] LibclangReparseTest.ReparseWithModule
Process 23113 stopped
* thread #1: tid = 0x710632, 0x000000010142308b
libclang.dylib`llvm::CrashRecoveryContext::registerCleanup(this=0xc000000000000000,
cleanup=0x000000010300ddc0) + 43 at CrashRecoveryContext.cpp:111, queue =
'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x000000010142308b
libclang.dylib`llvm::CrashRecoveryContext::registerCleanup(this=0xc000000000000000,
cleanup=0x000000010300ddc0) + 43 at CrashRecoveryContext.cpp:111
108 {
109 if (!cleanup)
110 return;
-> 111 if (head)
112 head->prev = cleanup;
113 cleanup->next = head;
114 head = cleanup;
(lldb) bt
* thread #1: tid = 0x710632, 0x000000010142308b
libclang.dylib`llvm::CrashRecoveryContext::registerCleanup(this=0xc000000000000000,
cleanup=0x000000010300ddc0) + 43 at CrashRecoveryContext.cpp:111, queue =
'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
* frame #0: 0x000000010142308b
libclang.dylib`llvm::CrashRecoveryContext::registerCleanup(this=0xc000000000000000,
cleanup=0x000000010300ddc0) + 43 at CrashRecoveryContext.cpp:111
frame #1: 0x000000010039ef10
libclang.dylib`CrashRecoveryContextCleanupRegistrar(this=0x00007fff5fbfd5d0,
x=0x000000010300eb60) + 80 at CrashRecoveryContext.h:196
frame #2: 0x0000000100395c7d
libclang.dylib`CrashRecoveryContextCleanupRegistrar(this=0x00007fff5fbfd5d0,
x=0x000000010300eb60) + 29 at CrashRecoveryContext.h:197
frame #3: 0x000000010037e1cd
libclang.dylib`clang::ASTUnit::Parse(this=0x0000000103802800,
OverrideMainBuffer=0x0000000103021720) + 477 at ASTUnit.cpp:1048
frame #4: 0x000000010038c126
libclang.dylib`clang::ASTUnit::Reparse(this=0x0000000103802800,
RemappedFiles=ArrayRef<std::__1::pair<std::__1::basic_string<char>,
llvm::MemoryBuffer *> > at 0x00007fff5fbfdf60) + 1414 at ASTUnit.cpp:2076
frame #5: 0x00000001001b3957
libclang.dylib`clang_reparseTranslationUnit_Impl(UserData=0x00007fff5fbfe910)
+ 2487 at CIndex.cpp:3094
frame #6: 0x00000001001f684f
libclang.dylib`operator(this=0x00007fff5fbfe840) + 31 at
CrashRecoveryContext.h:96
frame #7: 0x00000001001f6825 libclang.dylib`void
llvm::function_ref<void
(callable=140734799800384)>::callback_fn<llvm::CrashRecoveryContext::RunSafelyOnThread(void
(*)(void*), void*, unsigned int)::'lambda'()>(long) + 21 at STLExtras.h:75
frame #8: 0x0000000101423bf9 libclang.dylib`llvm::function_ref<void
(this=0x00007fff5fbfe808)>::operator()() const + 25 at STLExtras.h:85
frame #9: 0x0000000101423c75 libclang.dylib`void
llvm::function_ref<void
(callable=140734799800328)>::callback_fn<llvm::function_ref<void ()>
>(long) + 21 at STLExtras.h:75
frame #10: 0x0000000101423bf9 libclang.dylib`llvm::function_ref<void
(this=0x00007fff5fbfe7e0)>::operator()() const + 25 at STLExtras.h:85
frame #11: 0x0000000101423c75 libclang.dylib`void
llvm::function_ref<void
(callable=140734799800288)>::callback_fn<llvm::function_ref<void ()>
>(long) + 21 at STLExtras.h:75
frame #12: 0x0000000101423bf9 libclang.dylib`llvm::function_ref<void
(this=0x00007fff5fbfe730)>::operator()() const + 25 at STLExtras.h:85
frame #13: 0x000000010142351d
libclang.dylib`llvm::CrashRecoveryContext::RunSafely(this=0x00007fff5fbfe900,
Fn=function_ref<void ()> at 0x00007fff5fbfe730)>) + 237 at
CrashRecoveryContext.cpp:318
frame #14: 0x00000001014237c1
libclang.dylib`RunSafelyOnThread_Dispatch(UserData=0x00007fff5fbfe7e0) + 81
at CrashRecoveryContext.cpp:366
frame #15: 0x0000000101465f9d
libclang.dylib`llvm::llvm_execute_on_thread(Fn=0x0000000101423770,
UserData=0x00007fff5fbfe7e0, RequestedStackSize=8388608)(void*), void*,
unsigned int) + 29 at Threading.cpp:109
frame #16: 0x0000000101423702
libclang.dylib`llvm::CrashRecoveryContext::RunSafelyOnThread(this=0x00007fff5fbfe900,
Fn=function_ref<void ()> at 0x00007fff5fbfe808,
RequestedStackSize=8388608)>, unsigned int) + 98 at
CrashRecoveryContext.cpp:372
frame #17: 0x00000001001dd926
libclang.dylib`llvm::CrashRecoveryContext::RunSafelyOnThread(this=0x00007fff5fbfe900,
Fn=0x00000001001b2fa0, UserData=0x00007fff5fbfe910,
RequestedStackSize=8388608)(void*), void*, unsigned int) + 86 at
CrashRecoveryContext.h:96
frame #18: 0x00000001001b054d
libclang.dylib`clang::RunSafely(CRC=0x00007fff5fbfe900,
Fn=0x00000001001b2fa0, UserData=0x00007fff5fbfe910, Size=8388608)(void*),
void*, unsigned int) + 77 at CIndex.cpp:6809
frame #19: 0x00000001001b2f03
libclang.dylib`clang_reparseTranslationUnit(TU=0x00000001030056a0,
num_unsaved_files=0, unsaved_files=0x0000000000000000, options=0) + 339 at
CIndex.cpp:3123
frame #20: 0x0000000100005d6f
libclangTests`LibclangReparseTest::ReparseTU(this=0x0000000103004ad0,
num_unsaved_files=0, unsaved_files=0x0000000000000000) + 79 at
LibclangTest.cpp:385
frame #21: 0x0000000100004179
libclangTests`LibclangReparseTest_ReparseWithModule_Test::TestBody(this=0x0000000103004ad0)
+ 5257 at LibclangTest.cpp:455
frame #22: 0x0000000100041f83 libclangTests`void
testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test,
void>(object=0x0000000103004ad0, method=21 00 00 00 00 00 00 00,
location=0x00000001000b80bf)(), char const*) + 131 at gtest.cc:2090
frame #23: 0x0000000100030d8e libclangTests`void
testing::internal::HandleExceptionsInMethodIfSupported<testing::Test,
void>(object=0x0000000103004ad0, method=21 00 00 00 00 00 00 00,
location=0x00000001000b80bf)(), char const*) + 110 at gtest.cc:2142
frame #24: 0x000000010001bd35
libclangTests`testing::Test::Run(this=0x0000000103004ad0) + 197 at
gtest.cc:2161
frame #25: 0x000000010001c94b
libclangTests`testing::TestInfo::Run(this=0x0000000103004a00) + 219 at
gtest.cc:2309
frame #26: 0x000000010001d477
libclangTests`testing::TestCase::Run(this=0x0000000103004990) + 231 at
gtest.cc:2416
frame #27: 0x000000010002352e
libclangTests`testing::internal::UnitTestImpl::RunAllTests(this=0x0000000103003bd0)
+ 926 at gtest.cc:4205
frame #28: 0x000000010003ebf3 libclangTests`bool
testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl,
bool>(object=0x0000000103003bd0, method=90 31 02 00 01 00 00 00,
location=0x00000001000b8770)(), char const*) + 131 at gtest.cc:2090
frame #29: 0x0000000100032ffe libclangTests`bool
testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl,
bool>(object=0x0000000103003bd0, method=90 31 02 00 01 00 00 00,
location=0x00000001000b8770)(), char const*) + 110 at gtest.cc:2142
frame #30: 0x0000000100023174
libclangTests`testing::UnitTest::Run(this=0x00000001000c2cf0) + 100 at
gtest.cc:3839
frame #31: 0x000000010004a369 libclangTests`main(argc=1,
argv=0x00007fff5fbff9e0) + 89 at TestMain.cpp:48
On Wed, Jul 16, 2014 at 8:59 AM, Nico Weber <thakis at chromium.org> wrote:
> LibclangReparseTest.ReparseWithModule fails for me. (With `./configure
> --enable-optimized --enable-targets=host-only --enable-libedit=no
> --disable-threads --disable-pthreads --without-llvmgcc --without-llvmgxx`)
>
>
>
> On Mon, Jun 30, 2014 at 1:04 PM, Ben Langmuir <blangmuir at apple.com> wrote:
>
>> Author: benlangmuir
>> Date: Mon Jun 30 15:04:14 2014
>> New Revision: 212060
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=212060&view=rev
>> Log:
>> Consider module depedencies when checking a preamble in libclang
>>
>> Add module dependencies (header files, module map files) to the list of
>> files to check when deciding whether to rebuild a preamble. That fixes
>> using preambles with module imports so long as they are in
>> non-overridden files.
>>
>> My intent is to use to unify the existing dependency collectors to the
>> new “DependencyCollectory” interface from this commit, starting with the
>> DependencyFileGenerator.
>>
>> Modified:
>> cfe/trunk/include/clang/Frontend/CompilerInstance.h
>> cfe/trunk/include/clang/Frontend/Utils.h
>> cfe/trunk/lib/Frontend/ASTUnit.cpp
>> cfe/trunk/lib/Frontend/CompilerInstance.cpp
>> cfe/trunk/lib/Frontend/DependencyFile.cpp
>> cfe/trunk/unittests/libclang/LibclangTest.cpp
>>
>> Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=212060&r1=212059&r2=212060&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
>> +++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Mon Jun 30
>> 15:04:14 2014
>> @@ -111,6 +111,8 @@ class CompilerInstance : public ModuleLo
>> /// \brief The dependency file generator.
>> std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
>>
>> + std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
>> +
>> /// \brief The set of top-level modules that has already been loaded,
>> /// along with the module map
>> llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
>> @@ -711,6 +713,10 @@ public:
>> GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc)
>> override;
>>
>> bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc)
>> override;
>> +
>> + void addDependencyCollector(std::shared_ptr<DependencyCollector>
>> Listener) {
>> + DependencyCollectors.push_back(std::move(Listener));
>> + }
>> };
>>
>> } // end namespace clang
>>
>> Modified: cfe/trunk/include/clang/Frontend/Utils.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Utils.h?rev=212060&r1=212059&r2=212060&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Frontend/Utils.h (original)
>> +++ cfe/trunk/include/clang/Frontend/Utils.h Mon Jun 30 15:04:14 2014
>> @@ -69,6 +69,39 @@ void InitializePreprocessor(Preprocessor
>> void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
>> const PreprocessorOutputOptions &Opts);
>>
>> +/// An interface for collecting the dependencies of a compilation. Users
>> should
>> +/// use \c attachToPreprocessor and \c attachToASTReader to get all of
>> the
>> +/// dependencies.
>> +// FIXME: Migrate DependencyFileGen, DependencyGraphGen,
>> ModuleDepCollectory to
>> +// use this interface.
>> +class DependencyCollector {
>> +public:
>> + void attachToPreprocessor(Preprocessor &PP);
>> + void attachToASTReader(ASTReader &R);
>> + llvm::ArrayRef<std::string> getDependencies() const { return
>> Dependencies; }
>> +
>> + /// Called when a new file is seen. Return true if \p Filename should
>> be added
>> + /// to the list of dependencies.
>> + ///
>> + /// The default implementation ignores <built-in> and system files.
>> + virtual bool sawDependency(StringRef Filename, bool FromModule,
>> + bool IsSystem, bool IsModuleFile, bool
>> IsMissing);
>> + /// Called when the end of the main file is reached.
>> + virtual void finishedMainFile() { }
>> + /// Return true if system files should be passed to sawDependency().
>> + virtual bool needSystemDependencies() { return false; }
>> + virtual ~DependencyCollector();
>> +
>> +public: // implementation detail
>> + /// Add a dependency \p Filename if it has not been seen before and
>> + /// sawDependency() returns true.
>> + void maybeAddDependency(StringRef Filename, bool FromModule, bool
>> IsSystem,
>> + bool IsModuleFile, bool IsMissing);
>> +private:
>> + llvm::StringSet<> Seen;
>> + std::vector<std::string> Dependencies;
>> +};
>> +
>> /// Builds a depdenency file when attached to a Preprocessor (for
>> includes) and
>> /// ASTReader (for module imports), and writes it out at the end of
>> processing
>> /// a source file. Users should attach to the ast reader whenever a
>> module is
>>
>> Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=212060&r1=212059&r2=212060&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
>> +++ cfe/trunk/lib/Frontend/ASTUnit.cpp Mon Jun 30 15:04:14 2014
>> @@ -1609,6 +1609,9 @@ llvm::MemoryBuffer *ASTUnit::getMainBuff
>> Clang->setSourceManager(new SourceManager(getDiagnostics(),
>> Clang->getFileManager()));
>>
>> + auto PreambleDepCollector = std::make_shared<DependencyCollector>();
>> + Clang->addDependencyCollector(PreambleDepCollector);
>> +
>> std::unique_ptr<PrecompilePreambleAction> Act;
>> Act.reset(new PrecompilePreambleAction(*this));
>> if (!Act->BeginSourceFile(*Clang.get(),
>> Clang->getFrontendOpts().Inputs[0])) {
>> @@ -1657,29 +1660,20 @@ llvm::MemoryBuffer *ASTUnit::getMainBuff
>> // so we can verify whether they have changed or not.
>> FilesInPreamble.clear();
>> SourceManager &SourceMgr = Clang->getSourceManager();
>> - const llvm::MemoryBuffer *MainFileBuffer
>> - = SourceMgr.getBuffer(SourceMgr.getMainFileID());
>> - for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(),
>> - FEnd = SourceMgr.fileinfo_end();
>> - F != FEnd;
>> - ++F) {
>> - const FileEntry *File = F->second->OrigEntry;
>> - if (!File)
>> - continue;
>> - const llvm::MemoryBuffer *Buffer = F->second->getRawBuffer();
>> - if (Buffer == MainFileBuffer)
>> + for (auto &Filename : PreambleDepCollector->getDependencies()) {
>> + const FileEntry *File = Clang->getFileManager().getFile(Filename);
>> + if (!File || File ==
>> SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))
>> continue;
>> -
>> if (time_t ModTime = File->getModificationTime()) {
>> FilesInPreamble[File->getName()] = PreambleFileHash::createForFile(
>> - F->second->getSize(), ModTime);
>> + File->getSize(), ModTime);
>> } else {
>> - assert(F->second->getSize() == Buffer->getBufferSize());
>> + llvm::MemoryBuffer *Buffer =
>> SourceMgr.getMemoryBufferForFile(File);
>> FilesInPreamble[File->getName()] =
>> PreambleFileHash::createForMemoryBuffer(Buffer);
>> }
>> }
>> -
>> +
>> PreambleRebuildCounter = 1;
>> PreprocessorOpts.eraseRemappedFile(
>>
>> PreprocessorOpts.remapped_file_buffer_end() - 1);
>>
>> Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=212060&r1=212059&r2=212060&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
>> +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Jun 30 15:04:14 2014
>> @@ -288,6 +288,9 @@ void CompilerInstance::createPreprocesso
>> AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
>> getHeaderSearchOpts().Sysroot);
>>
>> + for (auto &Listener : DependencyCollectors)
>> + Listener->attachToPreprocessor(*PP);
>> +
>> // If we don't have a collector, but we are collecting module
>> dependencies,
>> // then we're the top level compiler instance and need to create one.
>> if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty())
>> @@ -1233,6 +1236,9 @@ CompilerInstance::loadModule(SourceLocat
>> if (ModuleDepCollector)
>> ModuleDepCollector->attachToASTReader(*ModuleManager);
>>
>> + for (auto &Listener : DependencyCollectors)
>> + Listener->attachToASTReader(*ModuleManager);
>> +
>> // Try to load the module file.
>> unsigned ARRFlags = ASTReader::ARR_OutOfDate |
>> ASTReader::ARR_Missing;
>> switch (ModuleManager->ReadAST(ModuleFileName,
>> serialization::MK_Module,
>>
>> Modified: cfe/trunk/lib/Frontend/DependencyFile.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DependencyFile.cpp?rev=212060&r1=212059&r2=212060&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Frontend/DependencyFile.cpp (original)
>> +++ cfe/trunk/lib/Frontend/DependencyFile.cpp Mon Jun 30 15:04:14 2014
>> @@ -29,6 +29,105 @@
>> using namespace clang;
>>
>> namespace {
>> +struct DepCollectorPPCallbacks : public PPCallbacks {
>> + DependencyCollector &DepCollector;
>> + SourceManager &SM;
>> + DepCollectorPPCallbacks(DependencyCollector &L, SourceManager &SM)
>> + : DepCollector(L), SM(SM) { }
>> +
>> + void FileChanged(SourceLocation Loc, FileChangeReason Reason,
>> + SrcMgr::CharacteristicKind FileType,
>> + FileID PrevFID) override {
>> + if (Reason != PPCallbacks::EnterFile)
>> + return;
>> +
>> + // Dependency generation really does want to go all the way to the
>> + // file entry for a source location to find out what is depended on.
>> + // We do not want #line markers to affect dependency generation!
>> + const FileEntry *FE =
>> + SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(Loc)));
>> + if (!FE)
>> + return;
>> +
>> + StringRef Filename = FE->getName();
>> +
>> + // Remove leading "./" (or ".//" or "././" etc.)
>> + while (Filename.size() > 2 && Filename[0] == '.' &&
>> + llvm::sys::path::is_separator(Filename[1])) {
>> + Filename = Filename.substr(1);
>> + while (llvm::sys::path::is_separator(Filename[0]))
>> + Filename = Filename.substr(1);
>> + }
>> +
>> + DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
>> + FileType != SrcMgr::C_User,
>> + /*IsModuleFile*/false,
>> /*IsMissing*/false);
>> + }
>> +
>> + void InclusionDirective(SourceLocation HashLoc, const Token
>> &IncludeTok,
>> + StringRef FileName, bool IsAngled,
>> + CharSourceRange FilenameRange, const FileEntry
>> *File,
>> + StringRef SearchPath, StringRef RelativePath,
>> + const Module *Imported) override {
>> + if (!File)
>> + DepCollector.maybeAddDependency(FileName, /*FromModule*/false,
>> + /*IsSystem*/false,
>> /*IsModuleFile*/false,
>> + /*IsMissing*/true);
>> + // Files that actually exist are handled by FileChanged.
>> + }
>> +
>> + void EndOfMainFile() override {
>> + DepCollector.finishedMainFile();
>> + }
>> +};
>> +
>> +struct DepCollectorASTListener : public ASTReaderListener {
>> + DependencyCollector &DepCollector;
>> + DepCollectorASTListener(DependencyCollector &L) : DepCollector(L) { }
>> + bool needsInputFileVisitation() override { return true; }
>> + bool needsSystemInputFileVisitation() override {
>> + return DepCollector.needSystemDependencies();
>> + }
>> + void visitModuleFile(StringRef Filename) override {
>> + DepCollector.maybeAddDependency(Filename, /*FromModule*/true,
>> + /*IsSystem*/false,
>> /*IsModuleFile*/true,
>> + /*IsMissing*/false);
>> + }
>> + bool visitInputFile(StringRef Filename, bool IsSystem,
>> + bool IsOverridden) override {
>> + if (IsOverridden)
>> + return true;
>> +
>> + DepCollector.maybeAddDependency(Filename, /*FromModule*/true,
>> IsSystem,
>> + /*IsModuleFile*/false,
>> /*IsMissing*/false);
>> + return true;
>> + }
>> +};
>> +} // end anonymous namespace
>> +
>> +void DependencyCollector::maybeAddDependency(StringRef Filename, bool
>> FromModule,
>> + bool IsSystem, bool
>> IsModuleFile,
>> + bool IsMissing) {
>> + if (Seen.insert(Filename) &&
>> + sawDependency(Filename, FromModule, IsSystem, IsModuleFile,
>> IsMissing))
>> + Dependencies.push_back(Filename);
>> +}
>> +
>> +bool DependencyCollector::sawDependency(StringRef Filename, bool
>> FromModule,
>> + bool IsSystem, bool IsModuleFile,
>> + bool IsMissing) {
>> + return Filename != "<built-in>" && (needSystemDependencies() ||
>> !IsSystem);
>> +}
>> +
>> +DependencyCollector::~DependencyCollector() { }
>> +void DependencyCollector::attachToPreprocessor(Preprocessor &PP) {
>> + PP.addPPCallbacks(new DepCollectorPPCallbacks(*this,
>> PP.getSourceManager()));
>> +}
>> +void DependencyCollector::attachToASTReader(ASTReader &R) {
>> + R.addListener(new DepCollectorASTListener(*this));
>> +}
>> +
>> +namespace {
>> /// Private implementation for DependencyFileGenerator
>> class DFGImpl : public PPCallbacks {
>> std::vector<std::string> Files;
>>
>> Modified: cfe/trunk/unittests/libclang/LibclangTest.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/libclang/LibclangTest.cpp?rev=212060&r1=212059&r2=212060&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/unittests/libclang/LibclangTest.cpp (original)
>> +++ cfe/trunk/unittests/libclang/LibclangTest.cpp Mon Jun 30 15:04:14 2014
>> @@ -340,9 +340,9 @@ TEST(libclang, ModuleMapDescriptor) {
>> }
>>
>> class LibclangReparseTest : public ::testing::Test {
>> - std::string TestDir;
>> std::set<std::string> Files;
>> public:
>> + std::string TestDir;
>> CXIndex Index;
>> CXTranslationUnit ClangTU;
>> unsigned TUFlags;
>> @@ -407,6 +407,39 @@ TEST_F(LibclangReparseTest, Reparse) {
>> nullptr, 0, TUFlags);
>> EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
>> DisplayDiagnostics();
>> +
>> + // Immedaitely reparse.
>> + ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
>> + EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
>> +
>> + std::string NewHeaderContents =
>> + std::string(HeaderTop) + "int baz;" + HeaderBottom;
>> + WriteFile(HeaderName, NewHeaderContents);
>> +
>> + // Reparse after fix.
>> + ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
>> + EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
>> +}
>> +
>> +TEST_F(LibclangReparseTest, ReparseWithModule) {
>> + const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
>> + const char *HeaderBottom = "\n};\n#endif\n";
>> + const char *MFile = "#include \"HeaderFile.h\"\nint main() {"
>> + " struct Foo foo; foo.bar = 7; foo.baz = 8;
>> }\n";
>> + const char *ModFile = "module A { header \"HeaderFile.h\" }\n";
>> + std::string HeaderName = "HeaderFile.h";
>> + std::string MName = "MFile.m";
>> + std::string ModName = "module.modulemap";
>> + WriteFile(MName, MFile);
>> + WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
>> + WriteFile(ModName, ModFile);
>> +
>> + const char *Args[] = { "-fmodules", "-I", TestDir.c_str() };
>> + int NumArgs = sizeof(Args) / sizeof(Args[0]);
>> + ClangTU = clang_parseTranslationUnit(Index, MName.c_str(), Args,
>> NumArgs,
>> + nullptr, 0, TUFlags);
>> + EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
>> + DisplayDiagnostics();
>>
>> // Immedaitely reparse.
>> ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140716/ccf8c90b/attachment.html>
More information about the cfe-commits
mailing list