[libclang] Indexing API: If the client requested to get a CXTranslationUnit after

indexing, honor all the TU options.

llvm-svn: 145229
This commit is contained in:
Argyrios Kyrtzidis 2011-11-28 04:56:00 +00:00
parent 67aa7db0a4
commit b11f5a4cbb
6 changed files with 89 additions and 14 deletions

View File

@ -674,10 +674,20 @@ public:
///
/// \param Unit - optionally an already created ASTUnit. Its ownership is not
/// transfered.
///
/// \param Persistent - if true the returned ASTUnit will be complete.
/// false means the caller is only interested in getting info through the
/// provided \see Action.
static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI,
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
ASTFrontendAction *Action = 0,
ASTUnit *Unit = 0);
ASTUnit *Unit = 0,
bool Persistent = true,
StringRef ResourceFilesPath = StringRef(),
bool OnlyLocalDecls = false,
bool CaptureDiagnostics = false,
bool PrecompilePreamble = false,
bool CacheCodeCompletionResults = false);
/// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
/// CompilerInvocation object.

View File

@ -37,6 +37,7 @@ public:
virtual void HandleInterestingDecl(DeclGroupRef D);
virtual void HandleTranslationUnit(ASTContext &Ctx);
virtual void HandleTagDeclDefinition(TagDecl *D);
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
virtual void CompleteTentativeDefinition(VarDecl *D);
virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired);
virtual ASTMutationListener *GetASTMutationListener();

View File

@ -27,6 +27,7 @@
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Frontend/Utils.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
@ -1649,21 +1650,33 @@ ASTUnit *ASTUnit::create(CompilerInvocation *CI,
ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
ASTFrontendAction *Action,
ASTUnit *Unit) {
ASTUnit *Unit,
bool Persistent,
StringRef ResourceFilesPath,
bool OnlyLocalDecls,
bool CaptureDiagnostics,
bool PrecompilePreamble,
bool CacheCodeCompletionResults) {
assert(CI && "A CompilerInvocation is required");
llvm::OwningPtr<ASTUnit> OwnAST;
ASTUnit *AST = Unit;
if (!AST) {
// Create the AST unit.
OwnAST.reset(create(CI, Diags));
OwnAST.reset(create(CI, Diags, CaptureDiagnostics));
AST = OwnAST.get();
}
AST->OnlyLocalDecls = false;
AST->CaptureDiagnostics = false;
if (!ResourceFilesPath.empty()) {
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
}
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
if (PrecompilePreamble)
AST->PreambleRebuildCounter = 2;
AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
AST->ShouldCacheCodeCompletionResults = false;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@ -1743,6 +1756,16 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
Clang->getFrontendOpts().Inputs[0].first))
return 0;
if (Persistent && !TrackerAct) {
Clang->getPreprocessor().addPPCallbacks(
new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue()));
std::vector<ASTConsumer*> Consumers;
if (Clang->hasASTConsumer())
Consumers.push_back(Clang->takeASTConsumer());
Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST,
AST->getCurrentTopLevelHashValue()));
Clang->setASTConsumer(new MultiplexConsumer(Consumers));
}
Act->Execute();
// Steal the created target, context, and preprocessor.

View File

@ -184,9 +184,10 @@ void MultiplexConsumer::Initialize(ASTContext &Context) {
}
bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
bool Continue = true;
for (size_t i = 0, e = Consumers.size(); i != e; ++i)
Consumers[i]->HandleTopLevelDecl(D);
return true;
Continue = Continue && Consumers[i]->HandleTopLevelDecl(D);
return Continue;
}
void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) {
@ -204,6 +205,11 @@ void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) {
Consumers[i]->HandleTagDeclDefinition(D);
}
void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
for (size_t i = 0, e = Consumers.size(); i != e; ++i)
Consumers[i]->HandleTopLevelDeclInObjCContainer(D);
}
void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
for (size_t i = 0, e = Consumers.size(); i != e; ++i)
Consumers[i]->CompleteTentativeDefinition(D);

View File

@ -1548,6 +1548,7 @@ typedef struct {
const char *check_prefix;
int first_check_printed;
int fail_for_error;
int abort;
} IndexData;
static void printCheck(IndexData *data) {
@ -1850,8 +1851,14 @@ static void index_indexEntityReference(CXClientData client_data,
printf("\n");
}
static int index_abortQuery(CXClientData client_data, void *reserved) {
IndexData *index_data;
index_data = (IndexData *)client_data;
return index_data->abort;
}
static IndexerCallbacks IndexCB = {
0, /*abortQuery*/
index_abortQuery,
index_diagnostic,
index_enteredMainFile,
index_ppIncludedFile,
@ -1894,6 +1901,7 @@ static int index_file(int argc, const char **argv) {
index_data.check_prefix = check_prefix;
index_data.first_check_printed = 0;
index_data.fail_for_error = 0;
index_data.abort = 0;
index_opts = 0;
if (getenv("CINDEXTEST_SUPPRESSREFS"))
@ -1948,6 +1956,7 @@ static int index_tu(int argc, const char **argv) {
index_data.check_prefix = check_prefix;
index_data.first_check_printed = 0;
index_data.fail_for_error = 0;
index_data.abort = 0;
index_opts = 0;
if (getenv("CINDEXTEST_SUPPRESSREFS"))

View File

@ -244,9 +244,6 @@ static void clang_indexSourceFile_Impl(void *UserData) {
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
(void)CXXIdx;
(void)TU_options;
CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer();
// Configure the diagnostics.
@ -333,9 +330,38 @@ static void clang_indexSourceFile_Impl(void *UserData) {
llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
IndexActionCleanup(IndexAction.get());
bool Persistent = requestedToGetTU;
StringRef ResourceFilesPath = CXXIdx->getClangResourcesPath();
bool OnlyLocalDecls = false;
bool CaptureDiagnostics = true;
bool PrecompilePreamble = false;
bool CacheCodeCompletionResults = false;
PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
PPOpts.DetailedRecord = false;
PPOpts.DetailedRecordIncludesNestedMacroExpansions = false;
if (requestedToGetTU) {
OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble;
// FIXME: Add a flag for modules.
CacheCodeCompletionResults
= TU_options & CXTranslationUnit_CacheCompletionResults;
if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) {
PPOpts.DetailedRecord = true;
PPOpts.DetailedRecordIncludesNestedMacroExpansions
= (TU_options & CXTranslationUnit_NestedMacroExpansions);
}
}
Unit = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags,
IndexAction.get(),
Unit);
Unit,
Persistent,
ResourceFilesPath,
OnlyLocalDecls,
CaptureDiagnostics,
PrecompilePreamble,
CacheCodeCompletionResults);
if (!Unit)
return;