clang API Documentation
00001 //===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // ASTUnit Implementation. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Frontend/ASTUnit.h" 00015 #include "clang/AST/ASTContext.h" 00016 #include "clang/AST/ASTConsumer.h" 00017 #include "clang/AST/DeclVisitor.h" 00018 #include "clang/AST/TypeOrdering.h" 00019 #include "clang/AST/StmtVisitor.h" 00020 #include "clang/Driver/Compilation.h" 00021 #include "clang/Driver/Driver.h" 00022 #include "clang/Driver/Job.h" 00023 #include "clang/Driver/ArgList.h" 00024 #include "clang/Driver/Options.h" 00025 #include "clang/Driver/Tool.h" 00026 #include "clang/Frontend/CompilerInstance.h" 00027 #include "clang/Frontend/FrontendActions.h" 00028 #include "clang/Frontend/FrontendDiagnostic.h" 00029 #include "clang/Frontend/FrontendOptions.h" 00030 #include "clang/Frontend/MultiplexConsumer.h" 00031 #include "clang/Frontend/Utils.h" 00032 #include "clang/Serialization/ASTReader.h" 00033 #include "clang/Serialization/ASTWriter.h" 00034 #include "clang/Lex/HeaderSearch.h" 00035 #include "clang/Lex/Preprocessor.h" 00036 #include "clang/Basic/TargetOptions.h" 00037 #include "clang/Basic/TargetInfo.h" 00038 #include "clang/Basic/Diagnostic.h" 00039 #include "llvm/ADT/ArrayRef.h" 00040 #include "llvm/ADT/StringExtras.h" 00041 #include "llvm/ADT/StringSet.h" 00042 #include "llvm/Support/Atomic.h" 00043 #include "llvm/Support/MemoryBuffer.h" 00044 #include "llvm/Support/Host.h" 00045 #include "llvm/Support/Path.h" 00046 #include "llvm/Support/raw_ostream.h" 00047 #include "llvm/Support/Timer.h" 00048 #include "llvm/Support/FileSystem.h" 00049 #include "llvm/Support/Mutex.h" 00050 #include "llvm/Support/MutexGuard.h" 00051 #include "llvm/Support/CrashRecoveryContext.h" 00052 #include <cstdlib> 00053 #include <cstdio> 00054 #include <sys/stat.h> 00055 using namespace clang; 00056 00057 using llvm::TimeRecord; 00058 00059 namespace { 00060 class SimpleTimer { 00061 bool WantTiming; 00062 TimeRecord Start; 00063 std::string Output; 00064 00065 public: 00066 explicit SimpleTimer(bool WantTiming) : WantTiming(WantTiming) { 00067 if (WantTiming) 00068 Start = TimeRecord::getCurrentTime(); 00069 } 00070 00071 void setOutput(const Twine &Output) { 00072 if (WantTiming) 00073 this->Output = Output.str(); 00074 } 00075 00076 ~SimpleTimer() { 00077 if (WantTiming) { 00078 TimeRecord Elapsed = TimeRecord::getCurrentTime(); 00079 Elapsed -= Start; 00080 llvm::errs() << Output << ':'; 00081 Elapsed.print(Elapsed, llvm::errs()); 00082 llvm::errs() << '\n'; 00083 } 00084 } 00085 }; 00086 00087 struct OnDiskData { 00088 /// \brief The file in which the precompiled preamble is stored. 00089 std::string PreambleFile; 00090 00091 /// \brief Temporary files that should be removed when the ASTUnit is 00092 /// destroyed. 00093 SmallVector<llvm::sys::Path, 4> TemporaryFiles; 00094 00095 /// \brief Erase temporary files. 00096 void CleanTemporaryFiles(); 00097 00098 /// \brief Erase the preamble file. 00099 void CleanPreambleFile(); 00100 00101 /// \brief Erase temporary files and the preamble file. 00102 void Cleanup(); 00103 }; 00104 } 00105 00106 static llvm::sys::SmartMutex<false> &getOnDiskMutex() { 00107 static llvm::sys::SmartMutex<false> M(/* recursive = */ true); 00108 return M; 00109 } 00110 00111 static void cleanupOnDiskMapAtExit(void); 00112 00113 typedef llvm::DenseMap<const ASTUnit *, OnDiskData *> OnDiskDataMap; 00114 static OnDiskDataMap &getOnDiskDataMap() { 00115 static OnDiskDataMap M; 00116 static bool hasRegisteredAtExit = false; 00117 if (!hasRegisteredAtExit) { 00118 hasRegisteredAtExit = true; 00119 atexit(cleanupOnDiskMapAtExit); 00120 } 00121 return M; 00122 } 00123 00124 static void cleanupOnDiskMapAtExit(void) { 00125 // No mutex required here since we are leaving the program. 00126 OnDiskDataMap &M = getOnDiskDataMap(); 00127 for (OnDiskDataMap::iterator I = M.begin(), E = M.end(); I != E; ++I) { 00128 // We don't worry about freeing the memory associated with OnDiskDataMap. 00129 // All we care about is erasing stale files. 00130 I->second->Cleanup(); 00131 } 00132 } 00133 00134 static OnDiskData &getOnDiskData(const ASTUnit *AU) { 00135 // We require the mutex since we are modifying the structure of the 00136 // DenseMap. 00137 llvm::MutexGuard Guard(getOnDiskMutex()); 00138 OnDiskDataMap &M = getOnDiskDataMap(); 00139 OnDiskData *&D = M[AU]; 00140 if (!D) 00141 D = new OnDiskData(); 00142 return *D; 00143 } 00144 00145 static void erasePreambleFile(const ASTUnit *AU) { 00146 getOnDiskData(AU).CleanPreambleFile(); 00147 } 00148 00149 static void removeOnDiskEntry(const ASTUnit *AU) { 00150 // We require the mutex since we are modifying the structure of the 00151 // DenseMap. 00152 llvm::MutexGuard Guard(getOnDiskMutex()); 00153 OnDiskDataMap &M = getOnDiskDataMap(); 00154 OnDiskDataMap::iterator I = M.find(AU); 00155 if (I != M.end()) { 00156 I->second->Cleanup(); 00157 delete I->second; 00158 M.erase(AU); 00159 } 00160 } 00161 00162 static void setPreambleFile(const ASTUnit *AU, llvm::StringRef preambleFile) { 00163 getOnDiskData(AU).PreambleFile = preambleFile; 00164 } 00165 00166 static const std::string &getPreambleFile(const ASTUnit *AU) { 00167 return getOnDiskData(AU).PreambleFile; 00168 } 00169 00170 void OnDiskData::CleanTemporaryFiles() { 00171 for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) 00172 TemporaryFiles[I].eraseFromDisk(); 00173 TemporaryFiles.clear(); 00174 } 00175 00176 void OnDiskData::CleanPreambleFile() { 00177 if (!PreambleFile.empty()) { 00178 llvm::sys::Path(PreambleFile).eraseFromDisk(); 00179 PreambleFile.clear(); 00180 } 00181 } 00182 00183 void OnDiskData::Cleanup() { 00184 CleanTemporaryFiles(); 00185 CleanPreambleFile(); 00186 } 00187 00188 void ASTUnit::clearFileLevelDecls() { 00189 for (FileDeclsTy::iterator 00190 I = FileDecls.begin(), E = FileDecls.end(); I != E; ++I) 00191 delete I->second; 00192 FileDecls.clear(); 00193 } 00194 00195 void ASTUnit::CleanTemporaryFiles() { 00196 getOnDiskData(this).CleanTemporaryFiles(); 00197 } 00198 00199 void ASTUnit::addTemporaryFile(const llvm::sys::Path &TempFile) { 00200 getOnDiskData(this).TemporaryFiles.push_back(TempFile); 00201 } 00202 00203 /// \brief After failing to build a precompiled preamble (due to 00204 /// errors in the source that occurs in the preamble), the number of 00205 /// reparses during which we'll skip even trying to precompile the 00206 /// preamble. 00207 const unsigned DefaultPreambleRebuildInterval = 5; 00208 00209 /// \brief Tracks the number of ASTUnit objects that are currently active. 00210 /// 00211 /// Used for debugging purposes only. 00212 static llvm::sys::cas_flag ActiveASTUnitObjects; 00213 00214 ASTUnit::ASTUnit(bool _MainFileIsAST) 00215 : Reader(0), OnlyLocalDecls(false), CaptureDiagnostics(false), 00216 MainFileIsAST(_MainFileIsAST), 00217 TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")), 00218 OwnsRemappedFileBuffers(true), 00219 NumStoredDiagnosticsFromDriver(0), 00220 PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), 00221 NumWarningsInPreamble(0), 00222 ShouldCacheCodeCompletionResults(false), 00223 CompletionCacheTopLevelHashValue(0), 00224 PreambleTopLevelHashValue(0), 00225 CurrentTopLevelHashValue(0), 00226 UnsafeToFree(false) { 00227 if (getenv("LIBCLANG_OBJTRACKING")) { 00228 llvm::sys::AtomicIncrement(&ActiveASTUnitObjects); 00229 fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects); 00230 } 00231 } 00232 00233 ASTUnit::~ASTUnit() { 00234 clearFileLevelDecls(); 00235 00236 // Clean up the temporary files and the preamble file. 00237 removeOnDiskEntry(this); 00238 00239 // Free the buffers associated with remapped files. We are required to 00240 // perform this operation here because we explicitly request that the 00241 // compiler instance *not* free these buffers for each invocation of the 00242 // parser. 00243 if (Invocation.getPtr() && OwnsRemappedFileBuffers) { 00244 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 00245 for (PreprocessorOptions::remapped_file_buffer_iterator 00246 FB = PPOpts.remapped_file_buffer_begin(), 00247 FBEnd = PPOpts.remapped_file_buffer_end(); 00248 FB != FBEnd; 00249 ++FB) 00250 delete FB->second; 00251 } 00252 00253 delete SavedMainFileBuffer; 00254 delete PreambleBuffer; 00255 00256 ClearCachedCompletionResults(); 00257 00258 if (getenv("LIBCLANG_OBJTRACKING")) { 00259 llvm::sys::AtomicDecrement(&ActiveASTUnitObjects); 00260 fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects); 00261 } 00262 } 00263 00264 void ASTUnit::setPreprocessor(Preprocessor *pp) { PP = pp; } 00265 00266 /// \brief Determine the set of code-completion contexts in which this 00267 /// declaration should be shown. 00268 static unsigned getDeclShowContexts(NamedDecl *ND, 00269 const LangOptions &LangOpts, 00270 bool &IsNestedNameSpecifier) { 00271 IsNestedNameSpecifier = false; 00272 00273 if (isa<UsingShadowDecl>(ND)) 00274 ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl()); 00275 if (!ND) 00276 return 0; 00277 00278 unsigned Contexts = 0; 00279 if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 00280 isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) { 00281 // Types can appear in these contexts. 00282 if (LangOpts.CPlusPlus || !isa<TagDecl>(ND)) 00283 Contexts |= (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 00284 | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 00285 | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 00286 | (1 << (CodeCompletionContext::CCC_Statement - 1)) 00287 | (1 << (CodeCompletionContext::CCC_Type - 1)) 00288 | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 00289 00290 // In C++, types can appear in expressions contexts (for functional casts). 00291 if (LangOpts.CPlusPlus) 00292 Contexts |= (1 << (CodeCompletionContext::CCC_Expression - 1)); 00293 00294 // In Objective-C, message sends can send interfaces. In Objective-C++, 00295 // all types are available due to functional casts. 00296 if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND)) 00297 Contexts |= (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 00298 00299 // In Objective-C, you can only be a subclass of another Objective-C class 00300 if (isa<ObjCInterfaceDecl>(ND)) 00301 Contexts |= (1 << (CodeCompletionContext::CCC_ObjCInterfaceName - 1)); 00302 00303 // Deal with tag names. 00304 if (isa<EnumDecl>(ND)) { 00305 Contexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1)); 00306 00307 // Part of the nested-name-specifier in C++0x. 00308 if (LangOpts.CPlusPlus0x) 00309 IsNestedNameSpecifier = true; 00310 } else if (RecordDecl *Record = dyn_cast<RecordDecl>(ND)) { 00311 if (Record->isUnion()) 00312 Contexts |= (1 << (CodeCompletionContext::CCC_UnionTag - 1)); 00313 else 00314 Contexts |= (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 00315 00316 if (LangOpts.CPlusPlus) 00317 IsNestedNameSpecifier = true; 00318 } else if (isa<ClassTemplateDecl>(ND)) 00319 IsNestedNameSpecifier = true; 00320 } else if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { 00321 // Values can appear in these contexts. 00322 Contexts = (1 << (CodeCompletionContext::CCC_Statement - 1)) 00323 | (1 << (CodeCompletionContext::CCC_Expression - 1)) 00324 | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 00325 | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)); 00326 } else if (isa<ObjCProtocolDecl>(ND)) { 00327 Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1)); 00328 } else if (isa<ObjCCategoryDecl>(ND)) { 00329 Contexts = (1 << (CodeCompletionContext::CCC_ObjCCategoryName - 1)); 00330 } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) { 00331 Contexts = (1 << (CodeCompletionContext::CCC_Namespace - 1)); 00332 00333 // Part of the nested-name-specifier. 00334 IsNestedNameSpecifier = true; 00335 } 00336 00337 return Contexts; 00338 } 00339 00340 void ASTUnit::CacheCodeCompletionResults() { 00341 if (!TheSema) 00342 return; 00343 00344 SimpleTimer Timer(WantTiming); 00345 Timer.setOutput("Cache global code completions for " + getMainFileName()); 00346 00347 // Clear out the previous results. 00348 ClearCachedCompletionResults(); 00349 00350 // Gather the set of global code completions. 00351 typedef CodeCompletionResult Result; 00352 SmallVector<Result, 8> Results; 00353 CachedCompletionAllocator = new GlobalCodeCompletionAllocator; 00354 TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator, 00355 getCodeCompletionTUInfo(), Results); 00356 00357 // Translate global code completions into cached completions. 00358 llvm::DenseMap<CanQualType, unsigned> CompletionTypes; 00359 00360 for (unsigned I = 0, N = Results.size(); I != N; ++I) { 00361 switch (Results[I].Kind) { 00362 case Result::RK_Declaration: { 00363 bool IsNestedNameSpecifier = false; 00364 CachedCodeCompletionResult CachedResult; 00365 CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema, 00366 *CachedCompletionAllocator, 00367 getCodeCompletionTUInfo()); 00368 CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration, 00369 Ctx->getLangOpts(), 00370 IsNestedNameSpecifier); 00371 CachedResult.Priority = Results[I].Priority; 00372 CachedResult.Kind = Results[I].CursorKind; 00373 CachedResult.Availability = Results[I].Availability; 00374 00375 // Keep track of the type of this completion in an ASTContext-agnostic 00376 // way. 00377 QualType UsageType = getDeclUsageType(*Ctx, Results[I].Declaration); 00378 if (UsageType.isNull()) { 00379 CachedResult.TypeClass = STC_Void; 00380 CachedResult.Type = 0; 00381 } else { 00382 CanQualType CanUsageType 00383 = Ctx->getCanonicalType(UsageType.getUnqualifiedType()); 00384 CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType); 00385 00386 // Determine whether we have already seen this type. If so, we save 00387 // ourselves the work of formatting the type string by using the 00388 // temporary, CanQualType-based hash table to find the associated value. 00389 unsigned &TypeValue = CompletionTypes[CanUsageType]; 00390 if (TypeValue == 0) { 00391 TypeValue = CompletionTypes.size(); 00392 CachedCompletionTypes[QualType(CanUsageType).getAsString()] 00393 = TypeValue; 00394 } 00395 00396 CachedResult.Type = TypeValue; 00397 } 00398 00399 CachedCompletionResults.push_back(CachedResult); 00400 00401 /// Handle nested-name-specifiers in C++. 00402 if (TheSema->Context.getLangOpts().CPlusPlus && 00403 IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) { 00404 // The contexts in which a nested-name-specifier can appear in C++. 00405 unsigned NNSContexts 00406 = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 00407 | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 00408 | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 00409 | (1 << (CodeCompletionContext::CCC_Statement - 1)) 00410 | (1 << (CodeCompletionContext::CCC_Expression - 1)) 00411 | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 00412 | (1 << (CodeCompletionContext::CCC_EnumTag - 1)) 00413 | (1 << (CodeCompletionContext::CCC_UnionTag - 1)) 00414 | (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1)) 00415 | (1 << (CodeCompletionContext::CCC_Type - 1)) 00416 | (1 << (CodeCompletionContext::CCC_PotentiallyQualifiedName - 1)) 00417 | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)); 00418 00419 if (isa<NamespaceDecl>(Results[I].Declaration) || 00420 isa<NamespaceAliasDecl>(Results[I].Declaration)) 00421 NNSContexts |= (1 << (CodeCompletionContext::CCC_Namespace - 1)); 00422 00423 if (unsigned RemainingContexts 00424 = NNSContexts & ~CachedResult.ShowInContexts) { 00425 // If there any contexts where this completion can be a 00426 // nested-name-specifier but isn't already an option, create a 00427 // nested-name-specifier completion. 00428 Results[I].StartsNestedNameSpecifier = true; 00429 CachedResult.Completion 00430 = Results[I].CreateCodeCompletionString(*TheSema, 00431 *CachedCompletionAllocator, 00432 getCodeCompletionTUInfo()); 00433 CachedResult.ShowInContexts = RemainingContexts; 00434 CachedResult.Priority = CCP_NestedNameSpecifier; 00435 CachedResult.TypeClass = STC_Void; 00436 CachedResult.Type = 0; 00437 CachedCompletionResults.push_back(CachedResult); 00438 } 00439 } 00440 break; 00441 } 00442 00443 case Result::RK_Keyword: 00444 case Result::RK_Pattern: 00445 // Ignore keywords and patterns; we don't care, since they are so 00446 // easily regenerated. 00447 break; 00448 00449 case Result::RK_Macro: { 00450 CachedCodeCompletionResult CachedResult; 00451 CachedResult.Completion 00452 = Results[I].CreateCodeCompletionString(*TheSema, 00453 *CachedCompletionAllocator, 00454 getCodeCompletionTUInfo()); 00455 CachedResult.ShowInContexts 00456 = (1 << (CodeCompletionContext::CCC_TopLevel - 1)) 00457 | (1 << (CodeCompletionContext::CCC_ObjCInterface - 1)) 00458 | (1 << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 00459 | (1 << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 00460 | (1 << (CodeCompletionContext::CCC_ClassStructUnion - 1)) 00461 | (1 << (CodeCompletionContext::CCC_Statement - 1)) 00462 | (1 << (CodeCompletionContext::CCC_Expression - 1)) 00463 | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 00464 | (1 << (CodeCompletionContext::CCC_MacroNameUse - 1)) 00465 | (1 << (CodeCompletionContext::CCC_PreprocessorExpression - 1)) 00466 | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 00467 | (1 << (CodeCompletionContext::CCC_OtherWithMacros - 1)); 00468 00469 CachedResult.Priority = Results[I].Priority; 00470 CachedResult.Kind = Results[I].CursorKind; 00471 CachedResult.Availability = Results[I].Availability; 00472 CachedResult.TypeClass = STC_Void; 00473 CachedResult.Type = 0; 00474 CachedCompletionResults.push_back(CachedResult); 00475 break; 00476 } 00477 } 00478 } 00479 00480 // Save the current top-level hash value. 00481 CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue; 00482 } 00483 00484 void ASTUnit::ClearCachedCompletionResults() { 00485 CachedCompletionResults.clear(); 00486 CachedCompletionTypes.clear(); 00487 CachedCompletionAllocator = 0; 00488 } 00489 00490 namespace { 00491 00492 /// \brief Gathers information from ASTReader that will be used to initialize 00493 /// a Preprocessor. 00494 class ASTInfoCollector : public ASTReaderListener { 00495 Preprocessor &PP; 00496 ASTContext &Context; 00497 LangOptions &LangOpt; 00498 HeaderSearch &HSI; 00499 IntrusiveRefCntPtr<TargetInfo> &Target; 00500 std::string &Predefines; 00501 unsigned &Counter; 00502 00503 unsigned NumHeaderInfos; 00504 00505 bool InitializedLanguage; 00506 public: 00507 ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, 00508 HeaderSearch &HSI, 00509 IntrusiveRefCntPtr<TargetInfo> &Target, 00510 std::string &Predefines, 00511 unsigned &Counter) 00512 : PP(PP), Context(Context), LangOpt(LangOpt), HSI(HSI), Target(Target), 00513 Predefines(Predefines), Counter(Counter), NumHeaderInfos(0), 00514 InitializedLanguage(false) {} 00515 00516 virtual bool ReadLanguageOptions(const LangOptions &LangOpts) { 00517 if (InitializedLanguage) 00518 return false; 00519 00520 LangOpt = LangOpts; 00521 00522 // Initialize the preprocessor. 00523 PP.Initialize(*Target); 00524 00525 // Initialize the ASTContext 00526 Context.InitBuiltinTypes(*Target); 00527 00528 InitializedLanguage = true; 00529 return false; 00530 } 00531 00532 virtual bool ReadTargetTriple(StringRef Triple) { 00533 // If we've already initialized the target, don't do it again. 00534 if (Target) 00535 return false; 00536 00537 // FIXME: This is broken, we should store the TargetOptions in the AST file. 00538 TargetOptions TargetOpts; 00539 TargetOpts.ABI = ""; 00540 TargetOpts.CXXABI = ""; 00541 TargetOpts.CPU = ""; 00542 TargetOpts.Features.clear(); 00543 TargetOpts.Triple = Triple; 00544 Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), TargetOpts); 00545 return false; 00546 } 00547 00548 virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, 00549 StringRef OriginalFileName, 00550 std::string &SuggestedPredefines, 00551 FileManager &FileMgr) { 00552 Predefines = Buffers[0].Data; 00553 for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { 00554 Predefines += Buffers[I].Data; 00555 } 00556 return false; 00557 } 00558 00559 virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID) { 00560 HSI.setHeaderFileInfoForUID(HFI, NumHeaderInfos++); 00561 } 00562 00563 virtual void ReadCounter(unsigned Value) { 00564 Counter = Value; 00565 } 00566 }; 00567 00568 class StoredDiagnosticConsumer : public DiagnosticConsumer { 00569 SmallVectorImpl<StoredDiagnostic> &StoredDiags; 00570 00571 public: 00572 explicit StoredDiagnosticConsumer( 00573 SmallVectorImpl<StoredDiagnostic> &StoredDiags) 00574 : StoredDiags(StoredDiags) { } 00575 00576 virtual void HandleDiagnostic(DiagnosticsEngine::Level Level, 00577 const Diagnostic &Info); 00578 00579 DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { 00580 // Just drop any diagnostics that come from cloned consumers; they'll 00581 // have different source managers anyway. 00582 // FIXME: We'd like to be able to capture these somehow, even if it's just 00583 // file/line/column, because they could occur when parsing module maps or 00584 // building modules on-demand. 00585 return new IgnoringDiagConsumer(); 00586 } 00587 }; 00588 00589 /// \brief RAII object that optionally captures diagnostics, if 00590 /// there is no diagnostic client to capture them already. 00591 class CaptureDroppedDiagnostics { 00592 DiagnosticsEngine &Diags; 00593 StoredDiagnosticConsumer Client; 00594 DiagnosticConsumer *PreviousClient; 00595 00596 public: 00597 CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags, 00598 SmallVectorImpl<StoredDiagnostic> &StoredDiags) 00599 : Diags(Diags), Client(StoredDiags), PreviousClient(0) 00600 { 00601 if (RequestCapture || Diags.getClient() == 0) { 00602 PreviousClient = Diags.takeClient(); 00603 Diags.setClient(&Client); 00604 } 00605 } 00606 00607 ~CaptureDroppedDiagnostics() { 00608 if (Diags.getClient() == &Client) { 00609 Diags.takeClient(); 00610 Diags.setClient(PreviousClient); 00611 } 00612 } 00613 }; 00614 00615 } // anonymous namespace 00616 00617 void StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level, 00618 const Diagnostic &Info) { 00619 // Default implementation (Warnings/errors count). 00620 DiagnosticConsumer::HandleDiagnostic(Level, Info); 00621 00622 StoredDiags.push_back(StoredDiagnostic(Level, Info)); 00623 } 00624 00625 const std::string &ASTUnit::getOriginalSourceFileName() { 00626 return OriginalSourceFile; 00627 } 00628 00629 llvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename, 00630 std::string *ErrorStr) { 00631 assert(FileMgr); 00632 return FileMgr->getBufferForFile(Filename, ErrorStr); 00633 } 00634 00635 /// \brief Configure the diagnostics object for use with ASTUnit. 00636 void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, 00637 const char **ArgBegin, const char **ArgEnd, 00638 ASTUnit &AST, bool CaptureDiagnostics) { 00639 if (!Diags.getPtr()) { 00640 // No diagnostics engine was provided, so create our own diagnostics object 00641 // with the default options. 00642 DiagnosticOptions DiagOpts; 00643 DiagnosticConsumer *Client = 0; 00644 if (CaptureDiagnostics) 00645 Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics); 00646 Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd-ArgBegin, 00647 ArgBegin, Client, 00648 /*ShouldOwnClient=*/true, 00649 /*ShouldCloneClient=*/false); 00650 } else if (CaptureDiagnostics) { 00651 Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics)); 00652 } 00653 } 00654 00655 ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, 00656 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 00657 const FileSystemOptions &FileSystemOpts, 00658 bool OnlyLocalDecls, 00659 RemappedFile *RemappedFiles, 00660 unsigned NumRemappedFiles, 00661 bool CaptureDiagnostics, 00662 bool AllowPCHWithCompilerErrors) { 00663 OwningPtr<ASTUnit> AST(new ASTUnit(true)); 00664 00665 // Recover resources if we crash before exiting this method. 00666 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 00667 ASTUnitCleanup(AST.get()); 00668 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 00669 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 00670 DiagCleanup(Diags.getPtr()); 00671 00672 ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 00673 00674 AST->OnlyLocalDecls = OnlyLocalDecls; 00675 AST->CaptureDiagnostics = CaptureDiagnostics; 00676 AST->Diagnostics = Diags; 00677 AST->FileMgr = new FileManager(FileSystemOpts); 00678 AST->SourceMgr = new SourceManager(AST->getDiagnostics(), 00679 AST->getFileManager()); 00680 AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager(), 00681 AST->getDiagnostics(), 00682 AST->ASTFileLangOpts, 00683 /*Target=*/0)); 00684 00685 for (unsigned I = 0; I != NumRemappedFiles; ++I) { 00686 FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 00687 if (const llvm::MemoryBuffer * 00688 memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 00689 // Create the file entry for the file that we're mapping from. 00690 const FileEntry *FromFile 00691 = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 00692 memBuf->getBufferSize(), 00693 0); 00694 if (!FromFile) { 00695 AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 00696 << RemappedFiles[I].first; 00697 delete memBuf; 00698 continue; 00699 } 00700 00701 // Override the contents of the "from" file with the contents of 00702 // the "to" file. 00703 AST->getSourceManager().overrideFileContents(FromFile, memBuf); 00704 00705 } else { 00706 const char *fname = fileOrBuf.get<const char *>(); 00707 const FileEntry *ToFile = AST->FileMgr->getFile(fname); 00708 if (!ToFile) { 00709 AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file) 00710 << RemappedFiles[I].first << fname; 00711 continue; 00712 } 00713 00714 // Create the file entry for the file that we're mapping from. 00715 const FileEntry *FromFile 00716 = AST->getFileManager().getVirtualFile(RemappedFiles[I].first, 00717 ToFile->getSize(), 00718 0); 00719 if (!FromFile) { 00720 AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file) 00721 << RemappedFiles[I].first; 00722 delete memBuf; 00723 continue; 00724 } 00725 00726 // Override the contents of the "from" file with the contents of 00727 // the "to" file. 00728 AST->getSourceManager().overrideFileContents(FromFile, ToFile); 00729 } 00730 } 00731 00732 // Gather Info for preprocessor construction later on. 00733 00734 HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); 00735 std::string Predefines; 00736 unsigned Counter; 00737 00738 OwningPtr<ASTReader> Reader; 00739 00740 AST->PP = new Preprocessor(AST->getDiagnostics(), AST->ASTFileLangOpts, 00741 /*Target=*/0, AST->getSourceManager(), HeaderInfo, 00742 *AST, 00743 /*IILookup=*/0, 00744 /*OwnsHeaderSearch=*/false, 00745 /*DelayInitialization=*/true); 00746 Preprocessor &PP = *AST->PP; 00747 00748 AST->Ctx = new ASTContext(AST->ASTFileLangOpts, 00749 AST->getSourceManager(), 00750 /*Target=*/0, 00751 PP.getIdentifierTable(), 00752 PP.getSelectorTable(), 00753 PP.getBuiltinInfo(), 00754 /* size_reserve = */0, 00755 /*DelayInitialization=*/true); 00756 ASTContext &Context = *AST->Ctx; 00757 00758 Reader.reset(new ASTReader(PP, Context, 00759 /*isysroot=*/"", 00760 /*DisableValidation=*/false, 00761 /*DisableStatCache=*/false, 00762 AllowPCHWithCompilerErrors)); 00763 00764 // Recover resources if we crash before exiting this method. 00765 llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> 00766 ReaderCleanup(Reader.get()); 00767 00768 Reader->setListener(new ASTInfoCollector(*AST->PP, Context, 00769 AST->ASTFileLangOpts, HeaderInfo, 00770 AST->Target, Predefines, Counter)); 00771 00772 switch (Reader->ReadAST(Filename, serialization::MK_MainFile)) { 00773 case ASTReader::Success: 00774 break; 00775 00776 case ASTReader::Failure: 00777 case ASTReader::IgnorePCH: 00778 AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch); 00779 return NULL; 00780 } 00781 00782 AST->OriginalSourceFile = Reader->getOriginalSourceFile(); 00783 00784 PP.setPredefines(Reader->getSuggestedPredefines()); 00785 PP.setCounterValue(Counter); 00786 00787 // Attach the AST reader to the AST context as an external AST 00788 // source, so that declarations will be deserialized from the 00789 // AST file as needed. 00790 ASTReader *ReaderPtr = Reader.get(); 00791 OwningPtr<ExternalASTSource> Source(Reader.take()); 00792 00793 // Unregister the cleanup for ASTReader. It will get cleaned up 00794 // by the ASTUnit cleanup. 00795 ReaderCleanup.unregister(); 00796 00797 Context.setExternalSource(Source); 00798 00799 // Create an AST consumer, even though it isn't used. 00800 AST->Consumer.reset(new ASTConsumer); 00801 00802 // Create a semantic analysis object and tell the AST reader about it. 00803 AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); 00804 AST->TheSema->Initialize(); 00805 ReaderPtr->InitializeSema(*AST->TheSema); 00806 AST->Reader = ReaderPtr; 00807 00808 return AST.take(); 00809 } 00810 00811 namespace { 00812 00813 /// \brief Preprocessor callback class that updates a hash value with the names 00814 /// of all macros that have been defined by the translation unit. 00815 class MacroDefinitionTrackerPPCallbacks : public PPCallbacks { 00816 unsigned &Hash; 00817 00818 public: 00819 explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { } 00820 00821 virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 00822 Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash); 00823 } 00824 }; 00825 00826 /// \brief Add the given declaration to the hash of all top-level entities. 00827 void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) { 00828 if (!D) 00829 return; 00830 00831 DeclContext *DC = D->getDeclContext(); 00832 if (!DC) 00833 return; 00834 00835 if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit())) 00836 return; 00837 00838 if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 00839 if (ND->getIdentifier()) 00840 Hash = llvm::HashString(ND->getIdentifier()->getName(), Hash); 00841 else if (DeclarationName Name = ND->getDeclName()) { 00842 std::string NameStr = Name.getAsString(); 00843 Hash = llvm::HashString(NameStr, Hash); 00844 } 00845 return; 00846 } 00847 } 00848 00849 class TopLevelDeclTrackerConsumer : public ASTConsumer { 00850 ASTUnit &Unit; 00851 unsigned &Hash; 00852 00853 public: 00854 TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash) 00855 : Unit(_Unit), Hash(Hash) { 00856 Hash = 0; 00857 } 00858 00859 void handleTopLevelDecl(Decl *D) { 00860 if (!D) 00861 return; 00862 00863 // FIXME: Currently ObjC method declarations are incorrectly being 00864 // reported as top-level declarations, even though their DeclContext 00865 // is the containing ObjC @interface/@implementation. This is a 00866 // fundamental problem in the parser right now. 00867 if (isa<ObjCMethodDecl>(D)) 00868 return; 00869 00870 AddTopLevelDeclarationToHash(D, Hash); 00871 Unit.addTopLevelDecl(D); 00872 00873 handleFileLevelDecl(D); 00874 } 00875 00876 void handleFileLevelDecl(Decl *D) { 00877 Unit.addFileLevelDecl(D); 00878 if (NamespaceDecl *NSD = dyn_cast<NamespaceDecl>(D)) { 00879 for (NamespaceDecl::decl_iterator 00880 I = NSD->decls_begin(), E = NSD->decls_end(); I != E; ++I) 00881 handleFileLevelDecl(*I); 00882 } 00883 } 00884 00885 bool HandleTopLevelDecl(DeclGroupRef D) { 00886 for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) 00887 handleTopLevelDecl(*it); 00888 return true; 00889 } 00890 00891 // We're not interested in "interesting" decls. 00892 void HandleInterestingDecl(DeclGroupRef) {} 00893 00894 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { 00895 for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) 00896 handleTopLevelDecl(*it); 00897 } 00898 }; 00899 00900 class TopLevelDeclTrackerAction : public ASTFrontendAction { 00901 public: 00902 ASTUnit &Unit; 00903 00904 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 00905 StringRef InFile) { 00906 CI.getPreprocessor().addPPCallbacks( 00907 new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); 00908 return new TopLevelDeclTrackerConsumer(Unit, 00909 Unit.getCurrentTopLevelHashValue()); 00910 } 00911 00912 public: 00913 TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {} 00914 00915 virtual bool hasCodeCompletionSupport() const { return false; } 00916 virtual TranslationUnitKind getTranslationUnitKind() { 00917 return Unit.getTranslationUnitKind(); 00918 } 00919 }; 00920 00921 class PrecompilePreambleConsumer : public PCHGenerator { 00922 ASTUnit &Unit; 00923 unsigned &Hash; 00924 std::vector<Decl *> TopLevelDecls; 00925 00926 public: 00927 PrecompilePreambleConsumer(ASTUnit &Unit, const Preprocessor &PP, 00928 StringRef isysroot, raw_ostream *Out) 00929 : PCHGenerator(PP, "", 0, isysroot, Out), Unit(Unit), 00930 Hash(Unit.getCurrentTopLevelHashValue()) { 00931 Hash = 0; 00932 } 00933 00934 virtual bool HandleTopLevelDecl(DeclGroupRef D) { 00935 for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) { 00936 Decl *D = *it; 00937 // FIXME: Currently ObjC method declarations are incorrectly being 00938 // reported as top-level declarations, even though their DeclContext 00939 // is the containing ObjC @interface/@implementation. This is a 00940 // fundamental problem in the parser right now. 00941 if (isa<ObjCMethodDecl>(D)) 00942 continue; 00943 AddTopLevelDeclarationToHash(D, Hash); 00944 TopLevelDecls.push_back(D); 00945 } 00946 return true; 00947 } 00948 00949 virtual void HandleTranslationUnit(ASTContext &Ctx) { 00950 PCHGenerator::HandleTranslationUnit(Ctx); 00951 if (!Unit.getDiagnostics().hasErrorOccurred()) { 00952 // Translate the top-level declarations we captured during 00953 // parsing into declaration IDs in the precompiled 00954 // preamble. This will allow us to deserialize those top-level 00955 // declarations when requested. 00956 for (unsigned I = 0, N = TopLevelDecls.size(); I != N; ++I) 00957 Unit.addTopLevelDeclFromPreamble( 00958 getWriter().getDeclID(TopLevelDecls[I])); 00959 } 00960 } 00961 }; 00962 00963 class PrecompilePreambleAction : public ASTFrontendAction { 00964 ASTUnit &Unit; 00965 00966 public: 00967 explicit PrecompilePreambleAction(ASTUnit &Unit) : Unit(Unit) {} 00968 00969 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 00970 StringRef InFile) { 00971 std::string Sysroot; 00972 std::string OutputFile; 00973 raw_ostream *OS = 0; 00974 if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot, 00975 OutputFile, 00976 OS)) 00977 return 0; 00978 00979 if (!CI.getFrontendOpts().RelocatablePCH) 00980 Sysroot.clear(); 00981 00982 CI.getPreprocessor().addPPCallbacks( 00983 new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue())); 00984 return new PrecompilePreambleConsumer(Unit, CI.getPreprocessor(), Sysroot, 00985 OS); 00986 } 00987 00988 virtual bool hasCodeCompletionSupport() const { return false; } 00989 virtual bool hasASTFileSupport() const { return false; } 00990 virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; } 00991 }; 00992 00993 } 00994 00995 static void checkAndRemoveNonDriverDiags(SmallVectorImpl<StoredDiagnostic> & 00996 StoredDiagnostics) { 00997 // Get rid of stored diagnostics except the ones from the driver which do not 00998 // have a source location. 00999 for (unsigned I = 0; I < StoredDiagnostics.size(); ++I) { 01000 if (StoredDiagnostics[I].getLocation().isValid()) { 01001 StoredDiagnostics.erase(StoredDiagnostics.begin()+I); 01002 --I; 01003 } 01004 } 01005 } 01006 01007 static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> & 01008 StoredDiagnostics, 01009 SourceManager &SM) { 01010 // The stored diagnostic has the old source manager in it; update 01011 // the locations to refer into the new source manager. Since we've 01012 // been careful to make sure that the source manager's state 01013 // before and after are identical, so that we can reuse the source 01014 // location itself. 01015 for (unsigned I = 0, N = StoredDiagnostics.size(); I < N; ++I) { 01016 if (StoredDiagnostics[I].getLocation().isValid()) { 01017 FullSourceLoc Loc(StoredDiagnostics[I].getLocation(), SM); 01018 StoredDiagnostics[I].setLocation(Loc); 01019 } 01020 } 01021 } 01022 01023 /// Parse the source file into a translation unit using the given compiler 01024 /// invocation, replacing the current translation unit. 01025 /// 01026 /// \returns True if a failure occurred that causes the ASTUnit not to 01027 /// contain any translation-unit information, false otherwise. 01028 bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { 01029 delete SavedMainFileBuffer; 01030 SavedMainFileBuffer = 0; 01031 01032 if (!Invocation) { 01033 delete OverrideMainBuffer; 01034 return true; 01035 } 01036 01037 // Create the compiler instance to use for building the AST. 01038 OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 01039 01040 // Recover resources if we crash before exiting this method. 01041 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 01042 CICleanup(Clang.get()); 01043 01044 IntrusiveRefCntPtr<CompilerInvocation> 01045 CCInvocation(new CompilerInvocation(*Invocation)); 01046 01047 Clang->setInvocation(CCInvocation.getPtr()); 01048 OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].File; 01049 01050 // Set up diagnostics, capturing any diagnostics that would 01051 // otherwise be dropped. 01052 Clang->setDiagnostics(&getDiagnostics()); 01053 01054 // Create the target instance. 01055 Clang->getTargetOpts().Features = TargetFeatures; 01056 Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 01057 Clang->getTargetOpts())); 01058 if (!Clang->hasTarget()) { 01059 delete OverrideMainBuffer; 01060 return true; 01061 } 01062 01063 // Inform the target of the language options. 01064 // 01065 // FIXME: We shouldn't need to do this, the target should be immutable once 01066 // created. This complexity should be lifted elsewhere. 01067 Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 01068 01069 assert(Clang->getFrontendOpts().Inputs.size() == 1 && 01070 "Invocation must have exactly one source file!"); 01071 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_AST && 01072 "FIXME: AST inputs not yet supported here!"); 01073 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_LLVM_IR && 01074 "IR inputs not support here!"); 01075 01076 // Configure the various subsystems. 01077 // FIXME: Should we retain the previous file manager? 01078 LangOpts = &Clang->getLangOpts(); 01079 FileSystemOpts = Clang->getFileSystemOpts(); 01080 FileMgr = new FileManager(FileSystemOpts); 01081 SourceMgr = new SourceManager(getDiagnostics(), *FileMgr); 01082 TheSema.reset(); 01083 Ctx = 0; 01084 PP = 0; 01085 Reader = 0; 01086 01087 // Clear out old caches and data. 01088 TopLevelDecls.clear(); 01089 clearFileLevelDecls(); 01090 CleanTemporaryFiles(); 01091 01092 if (!OverrideMainBuffer) { 01093 checkAndRemoveNonDriverDiags(StoredDiagnostics); 01094 TopLevelDeclsInPreamble.clear(); 01095 } 01096 01097 // Create a file manager object to provide access to and cache the filesystem. 01098 Clang->setFileManager(&getFileManager()); 01099 01100 // Create the source manager. 01101 Clang->setSourceManager(&getSourceManager()); 01102 01103 // If the main file has been overridden due to the use of a preamble, 01104 // make that override happen and introduce the preamble. 01105 PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts(); 01106 if (OverrideMainBuffer) { 01107 PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 01108 PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 01109 PreprocessorOpts.PrecompiledPreambleBytes.second 01110 = PreambleEndsAtStartOfLine; 01111 PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this); 01112 PreprocessorOpts.DisablePCHValidation = true; 01113 01114 // The stored diagnostic has the old source manager in it; update 01115 // the locations to refer into the new source manager. Since we've 01116 // been careful to make sure that the source manager's state 01117 // before and after are identical, so that we can reuse the source 01118 // location itself. 01119 checkAndSanitizeDiags(StoredDiagnostics, getSourceManager()); 01120 01121 // Keep track of the override buffer; 01122 SavedMainFileBuffer = OverrideMainBuffer; 01123 } 01124 01125 OwningPtr<TopLevelDeclTrackerAction> Act( 01126 new TopLevelDeclTrackerAction(*this)); 01127 01128 // Recover resources if we crash before exiting this method. 01129 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 01130 ActCleanup(Act.get()); 01131 01132 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) 01133 goto error; 01134 01135 if (OverrideMainBuffer) { 01136 std::string ModName = getPreambleFile(this); 01137 TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, 01138 getSourceManager(), PreambleDiagnostics, 01139 StoredDiagnostics); 01140 } 01141 01142 Act->Execute(); 01143 01144 transferASTDataFromCompilerInstance(*Clang); 01145 01146 Act->EndSourceFile(); 01147 01148 FailedParseDiagnostics.clear(); 01149 01150 return false; 01151 01152 error: 01153 // Remove the overridden buffer we used for the preamble. 01154 if (OverrideMainBuffer) { 01155 delete OverrideMainBuffer; 01156 SavedMainFileBuffer = 0; 01157 } 01158 01159 // Keep the ownership of the data in the ASTUnit because the client may 01160 // want to see the diagnostics. 01161 transferASTDataFromCompilerInstance(*Clang); 01162 FailedParseDiagnostics.swap(StoredDiagnostics); 01163 StoredDiagnostics.clear(); 01164 NumStoredDiagnosticsFromDriver = 0; 01165 return true; 01166 } 01167 01168 /// \brief Simple function to retrieve a path for a preamble precompiled header. 01169 static std::string GetPreamblePCHPath() { 01170 // FIXME: This is lame; sys::Path should provide this function (in particular, 01171 // it should know how to find the temporary files dir). 01172 // FIXME: This is really lame. I copied this code from the Driver! 01173 // FIXME: This is a hack so that we can override the preamble file during 01174 // crash-recovery testing, which is the only case where the preamble files 01175 // are not necessarily cleaned up. 01176 const char *TmpFile = ::getenv("CINDEXTEST_PREAMBLE_FILE"); 01177 if (TmpFile) 01178 return TmpFile; 01179 01180 std::string Error; 01181 const char *TmpDir = ::getenv("TMPDIR"); 01182 if (!TmpDir) 01183 TmpDir = ::getenv("TEMP"); 01184 if (!TmpDir) 01185 TmpDir = ::getenv("TMP"); 01186 #ifdef LLVM_ON_WIN32 01187 if (!TmpDir) 01188 TmpDir = ::getenv("USERPROFILE"); 01189 #endif 01190 if (!TmpDir) 01191 TmpDir = "/tmp"; 01192 llvm::sys::Path P(TmpDir); 01193 P.createDirectoryOnDisk(true); 01194 P.appendComponent("preamble"); 01195 P.appendSuffix("pch"); 01196 if (P.makeUnique(/*reuse_current=*/false, /*ErrMsg*/0)) 01197 return std::string(); 01198 01199 return P.str(); 01200 } 01201 01202 /// \brief Compute the preamble for the main file, providing the source buffer 01203 /// that corresponds to the main file along with a pair (bytes, start-of-line) 01204 /// that describes the preamble. 01205 std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 01206 ASTUnit::ComputePreamble(CompilerInvocation &Invocation, 01207 unsigned MaxLines, bool &CreatedBuffer) { 01208 FrontendOptions &FrontendOpts = Invocation.getFrontendOpts(); 01209 PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts(); 01210 CreatedBuffer = false; 01211 01212 // Try to determine if the main file has been remapped, either from the 01213 // command line (to another file) or directly through the compiler invocation 01214 // (to a memory buffer). 01215 llvm::MemoryBuffer *Buffer = 0; 01216 llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].File); 01217 if (const llvm::sys::FileStatus *MainFileStatus = MainFilePath.getFileStatus()) { 01218 // Check whether there is a file-file remapping of the main file 01219 for (PreprocessorOptions::remapped_file_iterator 01220 M = PreprocessorOpts.remapped_file_begin(), 01221 E = PreprocessorOpts.remapped_file_end(); 01222 M != E; 01223 ++M) { 01224 llvm::sys::PathWithStatus MPath(M->first); 01225 if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 01226 if (MainFileStatus->uniqueID == MStatus->uniqueID) { 01227 // We found a remapping. Try to load the resulting, remapped source. 01228 if (CreatedBuffer) { 01229 delete Buffer; 01230 CreatedBuffer = false; 01231 } 01232 01233 Buffer = getBufferForFile(M->second); 01234 if (!Buffer) 01235 return std::make_pair((llvm::MemoryBuffer*)0, 01236 std::make_pair(0, true)); 01237 CreatedBuffer = true; 01238 } 01239 } 01240 } 01241 01242 // Check whether there is a file-buffer remapping. It supercedes the 01243 // file-file remapping. 01244 for (PreprocessorOptions::remapped_file_buffer_iterator 01245 M = PreprocessorOpts.remapped_file_buffer_begin(), 01246 E = PreprocessorOpts.remapped_file_buffer_end(); 01247 M != E; 01248 ++M) { 01249 llvm::sys::PathWithStatus MPath(M->first); 01250 if (const llvm::sys::FileStatus *MStatus = MPath.getFileStatus()) { 01251 if (MainFileStatus->uniqueID == MStatus->uniqueID) { 01252 // We found a remapping. 01253 if (CreatedBuffer) { 01254 delete Buffer; 01255 CreatedBuffer = false; 01256 } 01257 01258 Buffer = const_cast<llvm::MemoryBuffer *>(M->second); 01259 } 01260 } 01261 } 01262 } 01263 01264 // If the main source file was not remapped, load it now. 01265 if (!Buffer) { 01266 Buffer = getBufferForFile(FrontendOpts.Inputs[0].File); 01267 if (!Buffer) 01268 return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true)); 01269 01270 CreatedBuffer = true; 01271 } 01272 01273 return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer, 01274 *Invocation.getLangOpts(), 01275 MaxLines)); 01276 } 01277 01278 static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old, 01279 unsigned NewSize, 01280 StringRef NewName) { 01281 llvm::MemoryBuffer *Result 01282 = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName); 01283 memcpy(const_cast<char*>(Result->getBufferStart()), 01284 Old->getBufferStart(), Old->getBufferSize()); 01285 memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 01286 ' ', NewSize - Old->getBufferSize() - 1); 01287 const_cast<char*>(Result->getBufferEnd())[-1] = '\n'; 01288 01289 return Result; 01290 } 01291 01292 /// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing 01293 /// the source file. 01294 /// 01295 /// This routine will compute the preamble of the main source file. If a 01296 /// non-trivial preamble is found, it will precompile that preamble into a 01297 /// precompiled header so that the precompiled preamble can be used to reduce 01298 /// reparsing time. If a precompiled preamble has already been constructed, 01299 /// this routine will determine if it is still valid and, if so, avoid 01300 /// rebuilding the precompiled preamble. 01301 /// 01302 /// \param AllowRebuild When true (the default), this routine is 01303 /// allowed to rebuild the precompiled preamble if it is found to be 01304 /// out-of-date. 01305 /// 01306 /// \param MaxLines When non-zero, the maximum number of lines that 01307 /// can occur within the preamble. 01308 /// 01309 /// \returns If the precompiled preamble can be used, returns a newly-allocated 01310 /// buffer that should be used in place of the main file when doing so. 01311 /// Otherwise, returns a NULL pointer. 01312 llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble( 01313 const CompilerInvocation &PreambleInvocationIn, 01314 bool AllowRebuild, 01315 unsigned MaxLines) { 01316 01317 IntrusiveRefCntPtr<CompilerInvocation> 01318 PreambleInvocation(new CompilerInvocation(PreambleInvocationIn)); 01319 FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts(); 01320 PreprocessorOptions &PreprocessorOpts 01321 = PreambleInvocation->getPreprocessorOpts(); 01322 01323 bool CreatedPreambleBuffer = false; 01324 std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 01325 = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer); 01326 01327 // If ComputePreamble() Take ownership of the preamble buffer. 01328 OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer; 01329 if (CreatedPreambleBuffer) 01330 OwnedPreambleBuffer.reset(NewPreamble.first); 01331 01332 if (!NewPreamble.second.first) { 01333 // We couldn't find a preamble in the main source. Clear out the current 01334 // preamble, if we have one. It's obviously no good any more. 01335 Preamble.clear(); 01336 erasePreambleFile(this); 01337 01338 // The next time we actually see a preamble, precompile it. 01339 PreambleRebuildCounter = 1; 01340 return 0; 01341 } 01342 01343 if (!Preamble.empty()) { 01344 // We've previously computed a preamble. Check whether we have the same 01345 // preamble now that we did before, and that there's enough space in 01346 // the main-file buffer within the precompiled preamble to fit the 01347 // new main file. 01348 if (Preamble.size() == NewPreamble.second.first && 01349 PreambleEndsAtStartOfLine == NewPreamble.second.second && 01350 NewPreamble.first->getBufferSize() < PreambleReservedSize-2 && 01351 memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(), 01352 NewPreamble.second.first) == 0) { 01353 // The preamble has not changed. We may be able to re-use the precompiled 01354 // preamble. 01355 01356 // Check that none of the files used by the preamble have changed. 01357 bool AnyFileChanged = false; 01358 01359 // First, make a record of those files that have been overridden via 01360 // remapping or unsaved_files. 01361 llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles; 01362 for (PreprocessorOptions::remapped_file_iterator 01363 R = PreprocessorOpts.remapped_file_begin(), 01364 REnd = PreprocessorOpts.remapped_file_end(); 01365 !AnyFileChanged && R != REnd; 01366 ++R) { 01367 struct stat StatBuf; 01368 if (FileMgr->getNoncachedStatValue(R->second, StatBuf)) { 01369 // If we can't stat the file we're remapping to, assume that something 01370 // horrible happened. 01371 AnyFileChanged = true; 01372 break; 01373 } 01374 01375 OverriddenFiles[R->first] = std::make_pair(StatBuf.st_size, 01376 StatBuf.st_mtime); 01377 } 01378 for (PreprocessorOptions::remapped_file_buffer_iterator 01379 R = PreprocessorOpts.remapped_file_buffer_begin(), 01380 REnd = PreprocessorOpts.remapped_file_buffer_end(); 01381 !AnyFileChanged && R != REnd; 01382 ++R) { 01383 // FIXME: Should we actually compare the contents of file->buffer 01384 // remappings? 01385 OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 01386 0); 01387 } 01388 01389 // Check whether anything has changed. 01390 for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 01391 F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end(); 01392 !AnyFileChanged && F != FEnd; 01393 ++F) { 01394 llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden 01395 = OverriddenFiles.find(F->first()); 01396 if (Overridden != OverriddenFiles.end()) { 01397 // This file was remapped; check whether the newly-mapped file 01398 // matches up with the previous mapping. 01399 if (Overridden->second != F->second) 01400 AnyFileChanged = true; 01401 continue; 01402 } 01403 01404 // The file was not remapped; check whether it has changed on disk. 01405 struct stat StatBuf; 01406 if (FileMgr->getNoncachedStatValue(F->first(), StatBuf)) { 01407 // If we can't stat the file, assume that something horrible happened. 01408 AnyFileChanged = true; 01409 } else if (StatBuf.st_size != F->second.first || 01410 StatBuf.st_mtime != F->second.second) 01411 AnyFileChanged = true; 01412 } 01413 01414 if (!AnyFileChanged) { 01415 // Okay! We can re-use the precompiled preamble. 01416 01417 // Set the state of the diagnostic object to mimic its state 01418 // after parsing the preamble. 01419 getDiagnostics().Reset(); 01420 ProcessWarningOptions(getDiagnostics(), 01421 PreambleInvocation->getDiagnosticOpts()); 01422 getDiagnostics().setNumWarnings(NumWarningsInPreamble); 01423 01424 // Create a version of the main file buffer that is padded to 01425 // buffer size we reserved when creating the preamble. 01426 return CreatePaddedMainFileBuffer(NewPreamble.first, 01427 PreambleReservedSize, 01428 FrontendOpts.Inputs[0].File); 01429 } 01430 } 01431 01432 // If we aren't allowed to rebuild the precompiled preamble, just 01433 // return now. 01434 if (!AllowRebuild) 01435 return 0; 01436 01437 // We can't reuse the previously-computed preamble. Build a new one. 01438 Preamble.clear(); 01439 PreambleDiagnostics.clear(); 01440 erasePreambleFile(this); 01441 PreambleRebuildCounter = 1; 01442 } else if (!AllowRebuild) { 01443 // We aren't allowed to rebuild the precompiled preamble; just 01444 // return now. 01445 return 0; 01446 } 01447 01448 // If the preamble rebuild counter > 1, it's because we previously 01449 // failed to build a preamble and we're not yet ready to try 01450 // again. Decrement the counter and return a failure. 01451 if (PreambleRebuildCounter > 1) { 01452 --PreambleRebuildCounter; 01453 return 0; 01454 } 01455 01456 // Create a temporary file for the precompiled preamble. In rare 01457 // circumstances, this can fail. 01458 std::string PreamblePCHPath = GetPreamblePCHPath(); 01459 if (PreamblePCHPath.empty()) { 01460 // Try again next time. 01461 PreambleRebuildCounter = 1; 01462 return 0; 01463 } 01464 01465 // We did not previously compute a preamble, or it can't be reused anyway. 01466 SimpleTimer PreambleTimer(WantTiming); 01467 PreambleTimer.setOutput("Precompiling preamble"); 01468 01469 // Create a new buffer that stores the preamble. The buffer also contains 01470 // extra space for the original contents of the file (which will be present 01471 // when we actually parse the file) along with more room in case the file 01472 // grows. 01473 PreambleReservedSize = NewPreamble.first->getBufferSize(); 01474 if (PreambleReservedSize < 4096) 01475 PreambleReservedSize = 8191; 01476 else 01477 PreambleReservedSize *= 2; 01478 01479 // Save the preamble text for later; we'll need to compare against it for 01480 // subsequent reparses. 01481 StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].File; 01482 Preamble.assign(FileMgr->getFile(MainFilename), 01483 NewPreamble.first->getBufferStart(), 01484 NewPreamble.first->getBufferStart() 01485 + NewPreamble.second.first); 01486 PreambleEndsAtStartOfLine = NewPreamble.second.second; 01487 01488 delete PreambleBuffer; 01489 PreambleBuffer 01490 = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize, 01491 FrontendOpts.Inputs[0].File); 01492 memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 01493 NewPreamble.first->getBufferStart(), Preamble.size()); 01494 memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 01495 ' ', PreambleReservedSize - Preamble.size() - 1); 01496 const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n'; 01497 01498 // Remap the main source file to the preamble buffer. 01499 llvm::sys::PathWithStatus MainFilePath(FrontendOpts.Inputs[0].File); 01500 PreprocessorOpts.addRemappedFile(MainFilePath.str(), PreambleBuffer); 01501 01502 // Tell the compiler invocation to generate a temporary precompiled header. 01503 FrontendOpts.ProgramAction = frontend::GeneratePCH; 01504 // FIXME: Generate the precompiled header into memory? 01505 FrontendOpts.OutputFile = PreamblePCHPath; 01506 PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 01507 PreprocessorOpts.PrecompiledPreambleBytes.second = false; 01508 01509 // Create the compiler instance to use for building the precompiled preamble. 01510 OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 01511 01512 // Recover resources if we crash before exiting this method. 01513 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 01514 CICleanup(Clang.get()); 01515 01516 Clang->setInvocation(&*PreambleInvocation); 01517 OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].File; 01518 01519 // Set up diagnostics, capturing all of the diagnostics produced. 01520 Clang->setDiagnostics(&getDiagnostics()); 01521 01522 // Create the target instance. 01523 Clang->getTargetOpts().Features = TargetFeatures; 01524 Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 01525 Clang->getTargetOpts())); 01526 if (!Clang->hasTarget()) { 01527 llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 01528 Preamble.clear(); 01529 PreambleRebuildCounter = DefaultPreambleRebuildInterval; 01530 PreprocessorOpts.eraseRemappedFile( 01531 PreprocessorOpts.remapped_file_buffer_end() - 1); 01532 return 0; 01533 } 01534 01535 // Inform the target of the language options. 01536 // 01537 // FIXME: We shouldn't need to do this, the target should be immutable once 01538 // created. This complexity should be lifted elsewhere. 01539 Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 01540 01541 assert(Clang->getFrontendOpts().Inputs.size() == 1 && 01542 "Invocation must have exactly one source file!"); 01543 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_AST && 01544 "FIXME: AST inputs not yet supported here!"); 01545 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_LLVM_IR && 01546 "IR inputs not support here!"); 01547 01548 // Clear out old caches and data. 01549 getDiagnostics().Reset(); 01550 ProcessWarningOptions(getDiagnostics(), Clang->getDiagnosticOpts()); 01551 checkAndRemoveNonDriverDiags(StoredDiagnostics); 01552 TopLevelDecls.clear(); 01553 TopLevelDeclsInPreamble.clear(); 01554 01555 // Create a file manager object to provide access to and cache the filesystem. 01556 Clang->setFileManager(new FileManager(Clang->getFileSystemOpts())); 01557 01558 // Create the source manager. 01559 Clang->setSourceManager(new SourceManager(getDiagnostics(), 01560 Clang->getFileManager())); 01561 01562 OwningPtr<PrecompilePreambleAction> Act; 01563 Act.reset(new PrecompilePreambleAction(*this)); 01564 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { 01565 llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 01566 Preamble.clear(); 01567 PreambleRebuildCounter = DefaultPreambleRebuildInterval; 01568 PreprocessorOpts.eraseRemappedFile( 01569 PreprocessorOpts.remapped_file_buffer_end() - 1); 01570 return 0; 01571 } 01572 01573 Act->Execute(); 01574 Act->EndSourceFile(); 01575 01576 if (Diagnostics->hasErrorOccurred()) { 01577 // There were errors parsing the preamble, so no precompiled header was 01578 // generated. Forget that we even tried. 01579 // FIXME: Should we leave a note for ourselves to try again? 01580 llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk(); 01581 Preamble.clear(); 01582 TopLevelDeclsInPreamble.clear(); 01583 PreambleRebuildCounter = DefaultPreambleRebuildInterval; 01584 PreprocessorOpts.eraseRemappedFile( 01585 PreprocessorOpts.remapped_file_buffer_end() - 1); 01586 return 0; 01587 } 01588 01589 // Transfer any diagnostics generated when parsing the preamble into the set 01590 // of preamble diagnostics. 01591 PreambleDiagnostics.clear(); 01592 PreambleDiagnostics.insert(PreambleDiagnostics.end(), 01593 stored_diag_afterDriver_begin(), stored_diag_end()); 01594 checkAndRemoveNonDriverDiags(StoredDiagnostics); 01595 01596 // Keep track of the preamble we precompiled. 01597 setPreambleFile(this, FrontendOpts.OutputFile); 01598 NumWarningsInPreamble = getDiagnostics().getNumWarnings(); 01599 01600 // Keep track of all of the files that the source manager knows about, 01601 // so we can verify whether they have changed or not. 01602 FilesInPreamble.clear(); 01603 SourceManager &SourceMgr = Clang->getSourceManager(); 01604 const llvm::MemoryBuffer *MainFileBuffer 01605 = SourceMgr.getBuffer(SourceMgr.getMainFileID()); 01606 for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(), 01607 FEnd = SourceMgr.fileinfo_end(); 01608 F != FEnd; 01609 ++F) { 01610 const FileEntry *File = F->second->OrigEntry; 01611 if (!File || F->second->getRawBuffer() == MainFileBuffer) 01612 continue; 01613 01614 FilesInPreamble[File->getName()] 01615 = std::make_pair(F->second->getSize(), File->getModificationTime()); 01616 } 01617 01618 PreambleRebuildCounter = 1; 01619 PreprocessorOpts.eraseRemappedFile( 01620 PreprocessorOpts.remapped_file_buffer_end() - 1); 01621 01622 // If the hash of top-level entities differs from the hash of the top-level 01623 // entities the last time we rebuilt the preamble, clear out the completion 01624 // cache. 01625 if (CurrentTopLevelHashValue != PreambleTopLevelHashValue) { 01626 CompletionCacheTopLevelHashValue = 0; 01627 PreambleTopLevelHashValue = CurrentTopLevelHashValue; 01628 } 01629 01630 return CreatePaddedMainFileBuffer(NewPreamble.first, 01631 PreambleReservedSize, 01632 FrontendOpts.Inputs[0].File); 01633 } 01634 01635 void ASTUnit::RealizeTopLevelDeclsFromPreamble() { 01636 std::vector<Decl *> Resolved; 01637 Resolved.reserve(TopLevelDeclsInPreamble.size()); 01638 ExternalASTSource &Source = *getASTContext().getExternalSource(); 01639 for (unsigned I = 0, N = TopLevelDeclsInPreamble.size(); I != N; ++I) { 01640 // Resolve the declaration ID to an actual declaration, possibly 01641 // deserializing the declaration in the process. 01642 Decl *D = Source.GetExternalDecl(TopLevelDeclsInPreamble[I]); 01643 if (D) 01644 Resolved.push_back(D); 01645 } 01646 TopLevelDeclsInPreamble.clear(); 01647 TopLevelDecls.insert(TopLevelDecls.begin(), Resolved.begin(), Resolved.end()); 01648 } 01649 01650 void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) { 01651 // Steal the created target, context, and preprocessor. 01652 TheSema.reset(CI.takeSema()); 01653 Consumer.reset(CI.takeASTConsumer()); 01654 Ctx = &CI.getASTContext(); 01655 PP = &CI.getPreprocessor(); 01656 CI.setSourceManager(0); 01657 CI.setFileManager(0); 01658 Target = &CI.getTarget(); 01659 Reader = CI.getModuleManager(); 01660 } 01661 01662 StringRef ASTUnit::getMainFileName() const { 01663 return Invocation->getFrontendOpts().Inputs[0].File; 01664 } 01665 01666 ASTUnit *ASTUnit::create(CompilerInvocation *CI, 01667 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 01668 bool CaptureDiagnostics) { 01669 OwningPtr<ASTUnit> AST; 01670 AST.reset(new ASTUnit(false)); 01671 ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 01672 AST->Diagnostics = Diags; 01673 AST->Invocation = CI; 01674 AST->FileSystemOpts = CI->getFileSystemOpts(); 01675 AST->FileMgr = new FileManager(AST->FileSystemOpts); 01676 AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr); 01677 01678 return AST.take(); 01679 } 01680 01681 ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI, 01682 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 01683 ASTFrontendAction *Action, 01684 ASTUnit *Unit, 01685 bool Persistent, 01686 StringRef ResourceFilesPath, 01687 bool OnlyLocalDecls, 01688 bool CaptureDiagnostics, 01689 bool PrecompilePreamble, 01690 bool CacheCodeCompletionResults, 01691 OwningPtr<ASTUnit> *ErrAST) { 01692 assert(CI && "A CompilerInvocation is required"); 01693 01694 OwningPtr<ASTUnit> OwnAST; 01695 ASTUnit *AST = Unit; 01696 if (!AST) { 01697 // Create the AST unit. 01698 OwnAST.reset(create(CI, Diags, CaptureDiagnostics)); 01699 AST = OwnAST.get(); 01700 } 01701 01702 if (!ResourceFilesPath.empty()) { 01703 // Override the resources path. 01704 CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 01705 } 01706 AST->OnlyLocalDecls = OnlyLocalDecls; 01707 AST->CaptureDiagnostics = CaptureDiagnostics; 01708 if (PrecompilePreamble) 01709 AST->PreambleRebuildCounter = 2; 01710 AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete; 01711 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 01712 01713 // Recover resources if we crash before exiting this method. 01714 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 01715 ASTUnitCleanup(OwnAST.get()); 01716 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 01717 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 01718 DiagCleanup(Diags.getPtr()); 01719 01720 // We'll manage file buffers ourselves. 01721 CI->getPreprocessorOpts().RetainRemappedFileBuffers = true; 01722 CI->getFrontendOpts().DisableFree = false; 01723 ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts()); 01724 01725 // Save the target features. 01726 AST->TargetFeatures = CI->getTargetOpts().Features; 01727 01728 // Create the compiler instance to use for building the AST. 01729 OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 01730 01731 // Recover resources if we crash before exiting this method. 01732 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 01733 CICleanup(Clang.get()); 01734 01735 Clang->setInvocation(CI); 01736 AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].File; 01737 01738 // Set up diagnostics, capturing any diagnostics that would 01739 // otherwise be dropped. 01740 Clang->setDiagnostics(&AST->getDiagnostics()); 01741 01742 // Create the target instance. 01743 Clang->getTargetOpts().Features = AST->TargetFeatures; 01744 Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 01745 Clang->getTargetOpts())); 01746 if (!Clang->hasTarget()) 01747 return 0; 01748 01749 // Inform the target of the language options. 01750 // 01751 // FIXME: We shouldn't need to do this, the target should be immutable once 01752 // created. This complexity should be lifted elsewhere. 01753 Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 01754 01755 assert(Clang->getFrontendOpts().Inputs.size() == 1 && 01756 "Invocation must have exactly one source file!"); 01757 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_AST && 01758 "FIXME: AST inputs not yet supported here!"); 01759 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_LLVM_IR && 01760 "IR inputs not supported here!"); 01761 01762 // Configure the various subsystems. 01763 AST->TheSema.reset(); 01764 AST->Ctx = 0; 01765 AST->PP = 0; 01766 AST->Reader = 0; 01767 01768 // Create a file manager object to provide access to and cache the filesystem. 01769 Clang->setFileManager(&AST->getFileManager()); 01770 01771 // Create the source manager. 01772 Clang->setSourceManager(&AST->getSourceManager()); 01773 01774 ASTFrontendAction *Act = Action; 01775 01776 OwningPtr<TopLevelDeclTrackerAction> TrackerAct; 01777 if (!Act) { 01778 TrackerAct.reset(new TopLevelDeclTrackerAction(*AST)); 01779 Act = TrackerAct.get(); 01780 } 01781 01782 // Recover resources if we crash before exiting this method. 01783 llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction> 01784 ActCleanup(TrackerAct.get()); 01785 01786 if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { 01787 AST->transferASTDataFromCompilerInstance(*Clang); 01788 if (OwnAST && ErrAST) 01789 ErrAST->swap(OwnAST); 01790 01791 return 0; 01792 } 01793 01794 if (Persistent && !TrackerAct) { 01795 Clang->getPreprocessor().addPPCallbacks( 01796 new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue())); 01797 std::vector<ASTConsumer*> Consumers; 01798 if (Clang->hasASTConsumer()) 01799 Consumers.push_back(Clang->takeASTConsumer()); 01800 Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST, 01801 AST->getCurrentTopLevelHashValue())); 01802 Clang->setASTConsumer(new MultiplexConsumer(Consumers)); 01803 } 01804 Act->Execute(); 01805 01806 // Steal the created target, context, and preprocessor. 01807 AST->transferASTDataFromCompilerInstance(*Clang); 01808 01809 Act->EndSourceFile(); 01810 01811 if (OwnAST) 01812 return OwnAST.take(); 01813 else 01814 return AST; 01815 } 01816 01817 bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) { 01818 if (!Invocation) 01819 return true; 01820 01821 // We'll manage file buffers ourselves. 01822 Invocation->getPreprocessorOpts().RetainRemappedFileBuffers = true; 01823 Invocation->getFrontendOpts().DisableFree = false; 01824 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 01825 01826 // Save the target features. 01827 TargetFeatures = Invocation->getTargetOpts().Features; 01828 01829 llvm::MemoryBuffer *OverrideMainBuffer = 0; 01830 if (PrecompilePreamble) { 01831 PreambleRebuildCounter = 2; 01832 OverrideMainBuffer 01833 = getMainBufferWithPrecompiledPreamble(*Invocation); 01834 } 01835 01836 SimpleTimer ParsingTimer(WantTiming); 01837 ParsingTimer.setOutput("Parsing " + getMainFileName()); 01838 01839 // Recover resources if we crash before exiting this method. 01840 llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer> 01841 MemBufferCleanup(OverrideMainBuffer); 01842 01843 return Parse(OverrideMainBuffer); 01844 } 01845 01846 ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI, 01847 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 01848 bool OnlyLocalDecls, 01849 bool CaptureDiagnostics, 01850 bool PrecompilePreamble, 01851 TranslationUnitKind TUKind, 01852 bool CacheCodeCompletionResults) { 01853 // Create the AST unit. 01854 OwningPtr<ASTUnit> AST; 01855 AST.reset(new ASTUnit(false)); 01856 ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics); 01857 AST->Diagnostics = Diags; 01858 AST->OnlyLocalDecls = OnlyLocalDecls; 01859 AST->CaptureDiagnostics = CaptureDiagnostics; 01860 AST->TUKind = TUKind; 01861 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 01862 AST->Invocation = CI; 01863 01864 // Recover resources if we crash before exiting this method. 01865 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 01866 ASTUnitCleanup(AST.get()); 01867 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 01868 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 01869 DiagCleanup(Diags.getPtr()); 01870 01871 return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take(); 01872 } 01873 01874 ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin, 01875 const char **ArgEnd, 01876 IntrusiveRefCntPtr<DiagnosticsEngine> Diags, 01877 StringRef ResourceFilesPath, 01878 bool OnlyLocalDecls, 01879 bool CaptureDiagnostics, 01880 RemappedFile *RemappedFiles, 01881 unsigned NumRemappedFiles, 01882 bool RemappedFilesKeepOriginalName, 01883 bool PrecompilePreamble, 01884 TranslationUnitKind TUKind, 01885 bool CacheCodeCompletionResults, 01886 bool AllowPCHWithCompilerErrors, 01887 bool SkipFunctionBodies, 01888 OwningPtr<ASTUnit> *ErrAST) { 01889 if (!Diags.getPtr()) { 01890 // No diagnostics engine was provided, so create our own diagnostics object 01891 // with the default options. 01892 DiagnosticOptions DiagOpts; 01893 Diags = CompilerInstance::createDiagnostics(DiagOpts, ArgEnd - ArgBegin, 01894 ArgBegin); 01895 } 01896 01897 SmallVector<StoredDiagnostic, 4> StoredDiagnostics; 01898 01899 IntrusiveRefCntPtr<CompilerInvocation> CI; 01900 01901 { 01902 01903 CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags, 01904 StoredDiagnostics); 01905 01906 CI = clang::createInvocationFromCommandLine( 01907 llvm::makeArrayRef(ArgBegin, ArgEnd), 01908 Diags); 01909 if (!CI) 01910 return 0; 01911 } 01912 01913 // Override any files that need remapping 01914 for (unsigned I = 0; I != NumRemappedFiles; ++I) { 01915 FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 01916 if (const llvm::MemoryBuffer * 01917 memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 01918 CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf); 01919 } else { 01920 const char *fname = fileOrBuf.get<const char *>(); 01921 CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname); 01922 } 01923 } 01924 PreprocessorOptions &PPOpts = CI->getPreprocessorOpts(); 01925 PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName; 01926 PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors; 01927 01928 // Override the resources path. 01929 CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath; 01930 01931 CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies; 01932 01933 // Create the AST unit. 01934 OwningPtr<ASTUnit> AST; 01935 AST.reset(new ASTUnit(false)); 01936 ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics); 01937 AST->Diagnostics = Diags; 01938 Diags = 0; // Zero out now to ease cleanup during crash recovery. 01939 AST->FileSystemOpts = CI->getFileSystemOpts(); 01940 AST->FileMgr = new FileManager(AST->FileSystemOpts); 01941 AST->OnlyLocalDecls = OnlyLocalDecls; 01942 AST->CaptureDiagnostics = CaptureDiagnostics; 01943 AST->TUKind = TUKind; 01944 AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults; 01945 AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size(); 01946 AST->StoredDiagnostics.swap(StoredDiagnostics); 01947 AST->Invocation = CI; 01948 CI = 0; // Zero out now to ease cleanup during crash recovery. 01949 01950 // Recover resources if we crash before exiting this method. 01951 llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit> 01952 ASTUnitCleanup(AST.get()); 01953 01954 if (AST->LoadFromCompilerInvocation(PrecompilePreamble)) { 01955 // Some error occurred, if caller wants to examine diagnostics, pass it the 01956 // ASTUnit. 01957 if (ErrAST) { 01958 AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics); 01959 ErrAST->swap(AST); 01960 } 01961 return 0; 01962 } 01963 01964 return AST.take(); 01965 } 01966 01967 bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) { 01968 if (!Invocation) 01969 return true; 01970 01971 clearFileLevelDecls(); 01972 01973 SimpleTimer ParsingTimer(WantTiming); 01974 ParsingTimer.setOutput("Reparsing " + getMainFileName()); 01975 01976 // Remap files. 01977 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 01978 PPOpts.DisableStatCache = true; 01979 for (PreprocessorOptions::remapped_file_buffer_iterator 01980 R = PPOpts.remapped_file_buffer_begin(), 01981 REnd = PPOpts.remapped_file_buffer_end(); 01982 R != REnd; 01983 ++R) { 01984 delete R->second; 01985 } 01986 Invocation->getPreprocessorOpts().clearRemappedFiles(); 01987 for (unsigned I = 0; I != NumRemappedFiles; ++I) { 01988 FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 01989 if (const llvm::MemoryBuffer * 01990 memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 01991 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 01992 memBuf); 01993 } else { 01994 const char *fname = fileOrBuf.get<const char *>(); 01995 Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, 01996 fname); 01997 } 01998 } 01999 02000 // If we have a preamble file lying around, or if we might try to 02001 // build a precompiled preamble, do so now. 02002 llvm::MemoryBuffer *OverrideMainBuffer = 0; 02003 if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0) 02004 OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation); 02005 02006 // Clear out the diagnostics state. 02007 getDiagnostics().Reset(); 02008 ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts()); 02009 if (OverrideMainBuffer) 02010 getDiagnostics().setNumWarnings(NumWarningsInPreamble); 02011 02012 // Parse the sources 02013 bool Result = Parse(OverrideMainBuffer); 02014 02015 // If we're caching global code-completion results, and the top-level 02016 // declarations have changed, clear out the code-completion cache. 02017 if (!Result && ShouldCacheCodeCompletionResults && 02018 CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue) 02019 CacheCodeCompletionResults(); 02020 02021 // We now need to clear out the completion info related to this translation 02022 // unit; it'll be recreated if necessary. 02023 CCTUInfo.reset(); 02024 02025 return Result; 02026 } 02027 02028 //----------------------------------------------------------------------------// 02029 // Code completion 02030 //----------------------------------------------------------------------------// 02031 02032 namespace { 02033 /// \brief Code completion consumer that combines the cached code-completion 02034 /// results from an ASTUnit with the code-completion results provided to it, 02035 /// then passes the result on to 02036 class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer { 02037 unsigned long long NormalContexts; 02038 ASTUnit &AST; 02039 CodeCompleteConsumer &Next; 02040 02041 public: 02042 AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next, 02043 bool IncludeMacros, bool IncludeCodePatterns, 02044 bool IncludeGlobals) 02045 : CodeCompleteConsumer(IncludeMacros, IncludeCodePatterns, IncludeGlobals, 02046 Next.isOutputBinary()), AST(AST), Next(Next) 02047 { 02048 // Compute the set of contexts in which we will look when we don't have 02049 // any information about the specific context. 02050 NormalContexts 02051 = (1LL << (CodeCompletionContext::CCC_TopLevel - 1)) 02052 | (1LL << (CodeCompletionContext::CCC_ObjCInterface - 1)) 02053 | (1LL << (CodeCompletionContext::CCC_ObjCImplementation - 1)) 02054 | (1LL << (CodeCompletionContext::CCC_ObjCIvarList - 1)) 02055 | (1LL << (CodeCompletionContext::CCC_Statement - 1)) 02056 | (1LL << (CodeCompletionContext::CCC_Expression - 1)) 02057 | (1LL << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1)) 02058 | (1LL << (CodeCompletionContext::CCC_DotMemberAccess - 1)) 02059 | (1LL << (CodeCompletionContext::CCC_ArrowMemberAccess - 1)) 02060 | (1LL << (CodeCompletionContext::CCC_ObjCPropertyAccess - 1)) 02061 | (1LL << (CodeCompletionContext::CCC_ObjCProtocolName - 1)) 02062 | (1LL << (CodeCompletionContext::CCC_ParenthesizedExpression - 1)) 02063 | (1LL << (CodeCompletionContext::CCC_Recovery - 1)); 02064 02065 if (AST.getASTContext().getLangOpts().CPlusPlus) 02066 NormalContexts |= (1LL << (CodeCompletionContext::CCC_EnumTag - 1)) 02067 | (1LL << (CodeCompletionContext::CCC_UnionTag - 1)) 02068 | (1LL << (CodeCompletionContext::CCC_ClassOrStructTag - 1)); 02069 } 02070 02071 virtual void ProcessCodeCompleteResults(Sema &S, 02072 CodeCompletionContext Context, 02073 CodeCompletionResult *Results, 02074 unsigned NumResults); 02075 02076 virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, 02077 OverloadCandidate *Candidates, 02078 unsigned NumCandidates) { 02079 Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates); 02080 } 02081 02082 virtual CodeCompletionAllocator &getAllocator() { 02083 return Next.getAllocator(); 02084 } 02085 02086 virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { 02087 return Next.getCodeCompletionTUInfo(); 02088 } 02089 }; 02090 } 02091 02092 /// \brief Helper function that computes which global names are hidden by the 02093 /// local code-completion results. 02094 static void CalculateHiddenNames(const CodeCompletionContext &Context, 02095 CodeCompletionResult *Results, 02096 unsigned NumResults, 02097 ASTContext &Ctx, 02098 llvm::StringSet<llvm::BumpPtrAllocator> &HiddenNames){ 02099 bool OnlyTagNames = false; 02100 switch (Context.getKind()) { 02101 case CodeCompletionContext::CCC_Recovery: 02102 case CodeCompletionContext::CCC_TopLevel: 02103 case CodeCompletionContext::CCC_ObjCInterface: 02104 case CodeCompletionContext::CCC_ObjCImplementation: 02105 case CodeCompletionContext::CCC_ObjCIvarList: 02106 case CodeCompletionContext::CCC_ClassStructUnion: 02107 case CodeCompletionContext::CCC_Statement: 02108 case CodeCompletionContext::CCC_Expression: 02109 case CodeCompletionContext::CCC_ObjCMessageReceiver: 02110 case CodeCompletionContext::CCC_DotMemberAccess: 02111 case CodeCompletionContext::CCC_ArrowMemberAccess: 02112 case CodeCompletionContext::CCC_ObjCPropertyAccess: 02113 case CodeCompletionContext::CCC_Namespace: 02114 case CodeCompletionContext::CCC_Type: 02115 case CodeCompletionContext::CCC_Name: 02116 case CodeCompletionContext::CCC_PotentiallyQualifiedName: 02117 case CodeCompletionContext::CCC_ParenthesizedExpression: 02118 case CodeCompletionContext::CCC_ObjCInterfaceName: 02119 break; 02120 02121 case CodeCompletionContext::CCC_EnumTag: 02122 case CodeCompletionContext::CCC_UnionTag: 02123 case CodeCompletionContext::CCC_ClassOrStructTag: 02124 OnlyTagNames = true; 02125 break; 02126 02127 case CodeCompletionContext::CCC_ObjCProtocolName: 02128 case CodeCompletionContext::CCC_MacroName: 02129 case CodeCompletionContext::CCC_MacroNameUse: 02130 case CodeCompletionContext::CCC_PreprocessorExpression: 02131 case CodeCompletionContext::CCC_PreprocessorDirective: 02132 case CodeCompletionContext::CCC_NaturalLanguage: 02133 case CodeCompletionContext::CCC_SelectorName: 02134 case CodeCompletionContext::CCC_TypeQualifiers: 02135 case CodeCompletionContext::CCC_Other: 02136 case CodeCompletionContext::CCC_OtherWithMacros: 02137 case CodeCompletionContext::CCC_ObjCInstanceMessage: 02138 case CodeCompletionContext::CCC_ObjCClassMessage: 02139 case CodeCompletionContext::CCC_ObjCCategoryName: 02140 // We're looking for nothing, or we're looking for names that cannot 02141 // be hidden. 02142 return; 02143 } 02144 02145 typedef CodeCompletionResult Result; 02146 for (unsigned I = 0; I != NumResults; ++I) { 02147 if (Results[I].Kind != Result::RK_Declaration) 02148 continue; 02149 02150 unsigned IDNS 02151 = Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace(); 02152 02153 bool Hiding = false; 02154 if (OnlyTagNames) 02155 Hiding = (IDNS & Decl::IDNS_Tag); 02156 else { 02157 unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member | 02158 Decl::IDNS_Namespace | Decl::IDNS_Ordinary | 02159 Decl::IDNS_NonMemberOperator); 02160 if (Ctx.getLangOpts().CPlusPlus) 02161 HiddenIDNS |= Decl::IDNS_Tag; 02162 Hiding = (IDNS & HiddenIDNS); 02163 } 02164 02165 if (!Hiding) 02166 continue; 02167 02168 DeclarationName Name = Results[I].Declaration->getDeclName(); 02169 if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo()) 02170 HiddenNames.insert(Identifier->getName()); 02171 else 02172 HiddenNames.insert(Name.getAsString()); 02173 } 02174 } 02175 02176 02177 void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S, 02178 CodeCompletionContext Context, 02179 CodeCompletionResult *Results, 02180 unsigned NumResults) { 02181 // Merge the results we were given with the results we cached. 02182 bool AddedResult = false; 02183 unsigned InContexts 02184 = (Context.getKind() == CodeCompletionContext::CCC_Recovery? NormalContexts 02185 : (1ULL << (Context.getKind() - 1))); 02186 // Contains the set of names that are hidden by "local" completion results. 02187 llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames; 02188 typedef CodeCompletionResult Result; 02189 SmallVector<Result, 8> AllResults; 02190 for (ASTUnit::cached_completion_iterator 02191 C = AST.cached_completion_begin(), 02192 CEnd = AST.cached_completion_end(); 02193 C != CEnd; ++C) { 02194 // If the context we are in matches any of the contexts we are 02195 // interested in, we'll add this result. 02196 if ((C->ShowInContexts & InContexts) == 0) 02197 continue; 02198 02199 // If we haven't added any results previously, do so now. 02200 if (!AddedResult) { 02201 CalculateHiddenNames(Context, Results, NumResults, S.Context, 02202 HiddenNames); 02203 AllResults.insert(AllResults.end(), Results, Results + NumResults); 02204 AddedResult = true; 02205 } 02206 02207 // Determine whether this global completion result is hidden by a local 02208 // completion result. If so, skip it. 02209 if (C->Kind != CXCursor_MacroDefinition && 02210 HiddenNames.count(C->Completion->getTypedText())) 02211 continue; 02212 02213 // Adjust priority based on similar type classes. 02214 unsigned Priority = C->Priority; 02215 CXCursorKind CursorKind = C->Kind; 02216 CodeCompletionString *Completion = C->Completion; 02217 if (!Context.getPreferredType().isNull()) { 02218 if (C->Kind == CXCursor_MacroDefinition) { 02219 Priority = getMacroUsagePriority(C->Completion->getTypedText(), 02220 S.getLangOpts(), 02221 Context.getPreferredType()->isAnyPointerType()); 02222 } else if (C->Type) { 02223 CanQualType Expected 02224 = S.Context.getCanonicalType( 02225 Context.getPreferredType().getUnqualifiedType()); 02226 SimplifiedTypeClass ExpectedSTC = getSimplifiedTypeClass(Expected); 02227 if (ExpectedSTC == C->TypeClass) { 02228 // We know this type is similar; check for an exact match. 02229 llvm::StringMap<unsigned> &CachedCompletionTypes 02230 = AST.getCachedCompletionTypes(); 02231 llvm::StringMap<unsigned>::iterator Pos 02232 = CachedCompletionTypes.find(QualType(Expected).getAsString()); 02233 if (Pos != CachedCompletionTypes.end() && Pos->second == C->Type) 02234 Priority /= CCF_ExactTypeMatch; 02235 else 02236 Priority /= CCF_SimilarTypeMatch; 02237 } 02238 } 02239 } 02240 02241 // Adjust the completion string, if required. 02242 if (C->Kind == CXCursor_MacroDefinition && 02243 Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) { 02244 // Create a new code-completion string that just contains the 02245 // macro name, without its arguments. 02246 CodeCompletionBuilder Builder(getAllocator(), getCodeCompletionTUInfo(), 02247 CCP_CodePattern, C->Availability); 02248 Builder.AddTypedTextChunk(C->Completion->getTypedText()); 02249 CursorKind = CXCursor_NotImplemented; 02250 Priority = CCP_CodePattern; 02251 Completion = Builder.TakeString(); 02252 } 02253 02254 AllResults.push_back(Result(Completion, Priority, CursorKind, 02255 C->Availability)); 02256 } 02257 02258 // If we did not add any cached completion results, just forward the 02259 // results we were given to the next consumer. 02260 if (!AddedResult) { 02261 Next.ProcessCodeCompleteResults(S, Context, Results, NumResults); 02262 return; 02263 } 02264 02265 Next.ProcessCodeCompleteResults(S, Context, AllResults.data(), 02266 AllResults.size()); 02267 } 02268 02269 02270 02271 void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column, 02272 RemappedFile *RemappedFiles, 02273 unsigned NumRemappedFiles, 02274 bool IncludeMacros, 02275 bool IncludeCodePatterns, 02276 CodeCompleteConsumer &Consumer, 02277 DiagnosticsEngine &Diag, LangOptions &LangOpts, 02278 SourceManager &SourceMgr, FileManager &FileMgr, 02279 SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, 02280 SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) { 02281 if (!Invocation) 02282 return; 02283 02284 SimpleTimer CompletionTimer(WantTiming); 02285 CompletionTimer.setOutput("Code completion @ " + File + ":" + 02286 Twine(Line) + ":" + Twine(Column)); 02287 02288 IntrusiveRefCntPtr<CompilerInvocation> 02289 CCInvocation(new CompilerInvocation(*Invocation)); 02290 02291 FrontendOptions &FrontendOpts = CCInvocation->getFrontendOpts(); 02292 PreprocessorOptions &PreprocessorOpts = CCInvocation->getPreprocessorOpts(); 02293 02294 FrontendOpts.ShowMacrosInCodeCompletion 02295 = IncludeMacros && CachedCompletionResults.empty(); 02296 FrontendOpts.ShowCodePatternsInCodeCompletion = IncludeCodePatterns; 02297 FrontendOpts.ShowGlobalSymbolsInCodeCompletion 02298 = CachedCompletionResults.empty(); 02299 FrontendOpts.CodeCompletionAt.FileName = File; 02300 FrontendOpts.CodeCompletionAt.Line = Line; 02301 FrontendOpts.CodeCompletionAt.Column = Column; 02302 02303 // Set the language options appropriately. 02304 LangOpts = *CCInvocation->getLangOpts(); 02305 02306 OwningPtr<CompilerInstance> Clang(new CompilerInstance()); 02307 02308 // Recover resources if we crash before exiting this method. 02309 llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> 02310 CICleanup(Clang.get()); 02311 02312 Clang->setInvocation(&*CCInvocation); 02313 OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].File; 02314 02315 // Set up diagnostics, capturing any diagnostics produced. 02316 Clang->setDiagnostics(&Diag); 02317 ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts()); 02318 CaptureDroppedDiagnostics Capture(true, 02319 Clang->getDiagnostics(), 02320 StoredDiagnostics); 02321 02322 // Create the target instance. 02323 Clang->getTargetOpts().Features = TargetFeatures; 02324 Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(), 02325 Clang->getTargetOpts())); 02326 if (!Clang->hasTarget()) { 02327 Clang->setInvocation(0); 02328 return; 02329 } 02330 02331 // Inform the target of the language options. 02332 // 02333 // FIXME: We shouldn't need to do this, the target should be immutable once 02334 // created. This complexity should be lifted elsewhere. 02335 Clang->getTarget().setForcedLangOptions(Clang->getLangOpts()); 02336 02337 assert(Clang->getFrontendOpts().Inputs.size() == 1 && 02338 "Invocation must have exactly one source file!"); 02339 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_AST && 02340 "FIXME: AST inputs not yet supported here!"); 02341 assert(Clang->getFrontendOpts().Inputs[0].Kind != IK_LLVM_IR && 02342 "IR inputs not support here!"); 02343 02344 02345 // Use the source and file managers that we were given. 02346 Clang->setFileManager(&FileMgr); 02347 Clang->setSourceManager(&SourceMgr); 02348 02349 // Remap files. 02350 PreprocessorOpts.clearRemappedFiles(); 02351 PreprocessorOpts.RetainRemappedFileBuffers = true; 02352 for (unsigned I = 0; I != NumRemappedFiles; ++I) { 02353 FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second; 02354 if (const llvm::MemoryBuffer * 02355 memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) { 02356 PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf); 02357 OwnedBuffers.push_back(memBuf); 02358 } else { 02359 const char *fname = fileOrBuf.get<const char *>(); 02360 PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname); 02361 } 02362 } 02363 02364 // Use the code completion consumer we were given, but adding any cached 02365 // code-completion results. 02366 AugmentedCodeCompleteConsumer *AugmentedConsumer 02367 = new AugmentedCodeCompleteConsumer(*this, Consumer, 02368 FrontendOpts.ShowMacrosInCodeCompletion, 02369 FrontendOpts.ShowCodePatternsInCodeCompletion, 02370 FrontendOpts.ShowGlobalSymbolsInCodeCompletion); 02371 Clang->setCodeCompletionConsumer(AugmentedConsumer); 02372 02373 Clang->getFrontendOpts().SkipFunctionBodies = true; 02374 02375 // If we have a precompiled preamble, try to use it. We only allow 02376 // the use of the precompiled preamble if we're if the completion 02377 // point is within the main file, after the end of the precompiled 02378 // preamble. 02379 llvm::MemoryBuffer *OverrideMainBuffer = 0; 02380 if (!getPreambleFile(this).empty()) { 02381 using llvm::sys::FileStatus; 02382 llvm::sys::PathWithStatus CompleteFilePath(File); 02383 llvm::sys::PathWithStatus MainPath(OriginalSourceFile); 02384 if (const FileStatus *CompleteFileStatus = CompleteFilePath.getFileStatus()) 02385 if (const FileStatus *MainStatus = MainPath.getFileStatus()) 02386 if (CompleteFileStatus->getUniqueID() == MainStatus->getUniqueID() && 02387 Line > 1) 02388 OverrideMainBuffer 02389 = getMainBufferWithPrecompiledPreamble(*CCInvocation, false, 02390 Line - 1); 02391 } 02392 02393 // If the main file has been overridden due to the use of a preamble, 02394 // make that override happen and introduce the preamble. 02395 PreprocessorOpts.DisableStatCache = true; 02396 StoredDiagnostics.insert(StoredDiagnostics.end(), 02397 stored_diag_begin(), 02398 stored_diag_afterDriver_begin()); 02399 if (OverrideMainBuffer) { 02400 PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer); 02401 PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size(); 02402 PreprocessorOpts.PrecompiledPreambleBytes.second 02403 = PreambleEndsAtStartOfLine; 02404 PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this); 02405 PreprocessorOpts.DisablePCHValidation = true; 02406 02407 OwnedBuffers.push_back(OverrideMainBuffer); 02408 } else { 02409 PreprocessorOpts.PrecompiledPreambleBytes.first = 0; 02410 PreprocessorOpts.PrecompiledPreambleBytes.second = false; 02411 } 02412 02413 // Disable the preprocessing record 02414 PreprocessorOpts.DetailedRecord = false; 02415 02416 OwningPtr<SyntaxOnlyAction> Act; 02417 Act.reset(new SyntaxOnlyAction); 02418 if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) { 02419 if (OverrideMainBuffer) { 02420 std::string ModName = getPreambleFile(this); 02421 TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, 02422 getSourceManager(), PreambleDiagnostics, 02423 StoredDiagnostics); 02424 } 02425 Act->Execute(); 02426 Act->EndSourceFile(); 02427 } 02428 02429 checkAndSanitizeDiags(StoredDiagnostics, getSourceManager()); 02430 } 02431 02432 CXSaveError ASTUnit::Save(StringRef File) { 02433 // Write to a temporary file and later rename it to the actual file, to avoid 02434 // possible race conditions. 02435 SmallString<128> TempPath; 02436 TempPath = File; 02437 TempPath += "-%%%%%%%%"; 02438 int fd; 02439 if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath, 02440 /*makeAbsolute=*/false)) 02441 return CXSaveError_Unknown; 02442 02443 // FIXME: Can we somehow regenerate the stat cache here, or do we need to 02444 // unconditionally create a stat cache when we parse the file? 02445 llvm::raw_fd_ostream Out(fd, /*shouldClose=*/true); 02446 02447 serialize(Out); 02448 Out.close(); 02449 if (Out.has_error()) { 02450 Out.clear_error(); 02451 return CXSaveError_Unknown; 02452 } 02453 02454 if (llvm::sys::fs::rename(TempPath.str(), File)) { 02455 bool exists; 02456 llvm::sys::fs::remove(TempPath.str(), exists); 02457 return CXSaveError_Unknown; 02458 } 02459 02460 return CXSaveError_None; 02461 } 02462 02463 bool ASTUnit::serialize(raw_ostream &OS) { 02464 bool hasErrors = getDiagnostics().hasErrorOccurred(); 02465 02466 SmallString<128> Buffer; 02467 llvm::BitstreamWriter Stream(Buffer); 02468 ASTWriter Writer(Stream); 02469 // FIXME: Handle modules 02470 Writer.WriteAST(getSema(), 0, std::string(), 0, "", hasErrors); 02471 02472 // Write the generated bitstream to "Out". 02473 if (!Buffer.empty()) 02474 OS.write((char *)&Buffer.front(), Buffer.size()); 02475 02476 return false; 02477 } 02478 02479 typedef ContinuousRangeMap<unsigned, int, 2> SLocRemap; 02480 02481 static void TranslateSLoc(SourceLocation &L, SLocRemap &Remap) { 02482 unsigned Raw = L.getRawEncoding(); 02483 const unsigned MacroBit = 1U << 31; 02484 L = SourceLocation::getFromRawEncoding((Raw & MacroBit) | 02485 ((Raw & ~MacroBit) + Remap.find(Raw & ~MacroBit)->second)); 02486 } 02487 02488 void ASTUnit::TranslateStoredDiagnostics( 02489 ASTReader *MMan, 02490 StringRef ModName, 02491 SourceManager &SrcMgr, 02492 const SmallVectorImpl<StoredDiagnostic> &Diags, 02493 SmallVectorImpl<StoredDiagnostic> &Out) { 02494 // The stored diagnostic has the old source manager in it; update 02495 // the locations to refer into the new source manager. We also need to remap 02496 // all the locations to the new view. This includes the diag location, any 02497 // associated source ranges, and the source ranges of associated fix-its. 02498 // FIXME: There should be a cleaner way to do this. 02499 02500 SmallVector<StoredDiagnostic, 4> Result; 02501 Result.reserve(Diags.size()); 02502 assert(MMan && "Don't have a module manager"); 02503 serialization::ModuleFile *Mod = MMan->ModuleMgr.lookup(ModName); 02504 assert(Mod && "Don't have preamble module"); 02505 SLocRemap &Remap = Mod->SLocRemap; 02506 for (unsigned I = 0, N = Diags.size(); I != N; ++I) { 02507 // Rebuild the StoredDiagnostic. 02508 const StoredDiagnostic &SD = Diags[I]; 02509 SourceLocation L = SD.getLocation(); 02510 TranslateSLoc(L, Remap); 02511 FullSourceLoc Loc(L, SrcMgr); 02512 02513 SmallVector<CharSourceRange, 4> Ranges; 02514 Ranges.reserve(SD.range_size()); 02515 for (StoredDiagnostic::range_iterator I = SD.range_begin(), 02516 E = SD.range_end(); 02517 I != E; ++I) { 02518 SourceLocation BL = I->getBegin(); 02519 TranslateSLoc(BL, Remap); 02520 SourceLocation EL = I->getEnd(); 02521 TranslateSLoc(EL, Remap); 02522 Ranges.push_back(CharSourceRange(SourceRange(BL, EL), I->isTokenRange())); 02523 } 02524 02525 SmallVector<FixItHint, 2> FixIts; 02526 FixIts.reserve(SD.fixit_size()); 02527 for (StoredDiagnostic::fixit_iterator I = SD.fixit_begin(), 02528 E = SD.fixit_end(); 02529 I != E; ++I) { 02530 FixIts.push_back(FixItHint()); 02531 FixItHint &FH = FixIts.back(); 02532 FH.CodeToInsert = I->CodeToInsert; 02533 SourceLocation BL = I->RemoveRange.getBegin(); 02534 TranslateSLoc(BL, Remap); 02535 SourceLocation EL = I->RemoveRange.getEnd(); 02536 TranslateSLoc(EL, Remap); 02537 FH.RemoveRange = CharSourceRange(SourceRange(BL, EL), 02538 I->RemoveRange.isTokenRange()); 02539 } 02540 02541 Result.push_back(StoredDiagnostic(SD.getLevel(), SD.getID(), 02542 SD.getMessage(), Loc, Ranges, FixIts)); 02543 } 02544 Result.swap(Out); 02545 } 02546 02547 static inline bool compLocDecl(std::pair<unsigned, Decl *> L, 02548 std::pair<unsigned, Decl *> R) { 02549 return L.first < R.first; 02550 } 02551 02552 void ASTUnit::addFileLevelDecl(Decl *D) { 02553 assert(D); 02554 02555 // We only care about local declarations. 02556 if (D->isFromASTFile()) 02557 return; 02558 02559 SourceManager &SM = *SourceMgr; 02560 SourceLocation Loc = D->getLocation(); 02561 if (Loc.isInvalid() || !SM.isLocalSourceLocation(Loc)) 02562 return; 02563 02564 // We only keep track of the file-level declarations of each file. 02565 if (!D->getLexicalDeclContext()->isFileContext()) 02566 return; 02567 02568 SourceLocation FileLoc = SM.getFileLoc(Loc); 02569 assert(SM.isLocalSourceLocation(FileLoc)); 02570 FileID FID; 02571 unsigned Offset; 02572 llvm::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc); 02573 if (FID.isInvalid()) 02574 return; 02575 02576 LocDeclsTy *&Decls = FileDecls[FID]; 02577 if (!Decls) 02578 Decls = new LocDeclsTy(); 02579 02580 std::pair<unsigned, Decl *> LocDecl(Offset, D); 02581 02582 if (Decls->empty() || Decls->back().first <= Offset) { 02583 Decls->push_back(LocDecl); 02584 return; 02585 } 02586 02587 LocDeclsTy::iterator 02588 I = std::upper_bound(Decls->begin(), Decls->end(), LocDecl, compLocDecl); 02589 02590 Decls->insert(I, LocDecl); 02591 } 02592 02593 void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, 02594 SmallVectorImpl<Decl *> &Decls) { 02595 if (File.isInvalid()) 02596 return; 02597 02598 if (SourceMgr->isLoadedFileID(File)) { 02599 assert(Ctx->getExternalSource() && "No external source!"); 02600 return Ctx->getExternalSource()->FindFileRegionDecls(File, Offset, Length, 02601 Decls); 02602 } 02603 02604 FileDeclsTy::iterator I = FileDecls.find(File); 02605 if (I == FileDecls.end()) 02606 return; 02607 02608 LocDeclsTy &LocDecls = *I->second; 02609 if (LocDecls.empty()) 02610 return; 02611 02612 LocDeclsTy::iterator 02613 BeginIt = std::lower_bound(LocDecls.begin(), LocDecls.end(), 02614 std::make_pair(Offset, (Decl*)0), compLocDecl); 02615 if (BeginIt != LocDecls.begin()) 02616 --BeginIt; 02617 02618 // If we are pointing at a top-level decl inside an objc container, we need 02619 // to backtrack until we find it otherwise we will fail to report that the 02620 // region overlaps with an objc container. 02621 while (BeginIt != LocDecls.begin() && 02622 BeginIt->second->isTopLevelDeclInObjCContainer()) 02623 --BeginIt; 02624 02625 LocDeclsTy::iterator 02626 EndIt = std::upper_bound(LocDecls.begin(), LocDecls.end(), 02627 std::make_pair(Offset+Length, (Decl*)0), 02628 compLocDecl); 02629 if (EndIt != LocDecls.end()) 02630 ++EndIt; 02631 02632 for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt) 02633 Decls.push_back(DIt->second); 02634 } 02635 02636 SourceLocation ASTUnit::getLocation(const FileEntry *File, 02637 unsigned Line, unsigned Col) const { 02638 const SourceManager &SM = getSourceManager(); 02639 SourceLocation Loc = SM.translateFileLineCol(File, Line, Col); 02640 return SM.getMacroArgExpandedLocation(Loc); 02641 } 02642 02643 SourceLocation ASTUnit::getLocation(const FileEntry *File, 02644 unsigned Offset) const { 02645 const SourceManager &SM = getSourceManager(); 02646 SourceLocation FileLoc = SM.translateFileLineCol(File, 1, 1); 02647 return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset)); 02648 } 02649 02650 /// \brief If \arg Loc is a loaded location from the preamble, returns 02651 /// the corresponding local location of the main file, otherwise it returns 02652 /// \arg Loc. 02653 SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) { 02654 FileID PreambleID; 02655 if (SourceMgr) 02656 PreambleID = SourceMgr->getPreambleFileID(); 02657 02658 if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid()) 02659 return Loc; 02660 02661 unsigned Offs; 02662 if (SourceMgr->isInFileID(Loc, PreambleID, &Offs) && Offs < Preamble.size()) { 02663 SourceLocation FileLoc 02664 = SourceMgr->getLocForStartOfFile(SourceMgr->getMainFileID()); 02665 return FileLoc.getLocWithOffset(Offs); 02666 } 02667 02668 return Loc; 02669 } 02670 02671 /// \brief If \arg Loc is a local location of the main file but inside the 02672 /// preamble chunk, returns the corresponding loaded location from the 02673 /// preamble, otherwise it returns \arg Loc. 02674 SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) { 02675 FileID PreambleID; 02676 if (SourceMgr) 02677 PreambleID = SourceMgr->getPreambleFileID(); 02678 02679 if (Loc.isInvalid() || Preamble.empty() || PreambleID.isInvalid()) 02680 return Loc; 02681 02682 unsigned Offs; 02683 if (SourceMgr->isInFileID(Loc, SourceMgr->getMainFileID(), &Offs) && 02684 Offs < Preamble.size()) { 02685 SourceLocation FileLoc = SourceMgr->getLocForStartOfFile(PreambleID); 02686 return FileLoc.getLocWithOffset(Offs); 02687 } 02688 02689 return Loc; 02690 } 02691 02692 bool ASTUnit::isInPreambleFileID(SourceLocation Loc) { 02693 FileID FID; 02694 if (SourceMgr) 02695 FID = SourceMgr->getPreambleFileID(); 02696 02697 if (Loc.isInvalid() || FID.isInvalid()) 02698 return false; 02699 02700 return SourceMgr->isInFileID(Loc, FID); 02701 } 02702 02703 bool ASTUnit::isInMainFileID(SourceLocation Loc) { 02704 FileID FID; 02705 if (SourceMgr) 02706 FID = SourceMgr->getMainFileID(); 02707 02708 if (Loc.isInvalid() || FID.isInvalid()) 02709 return false; 02710 02711 return SourceMgr->isInFileID(Loc, FID); 02712 } 02713 02714 SourceLocation ASTUnit::getEndOfPreambleFileID() { 02715 FileID FID; 02716 if (SourceMgr) 02717 FID = SourceMgr->getPreambleFileID(); 02718 02719 if (FID.isInvalid()) 02720 return SourceLocation(); 02721 02722 return SourceMgr->getLocForEndOfFile(FID); 02723 } 02724 02725 SourceLocation ASTUnit::getStartOfMainFileID() { 02726 FileID FID; 02727 if (SourceMgr) 02728 FID = SourceMgr->getMainFileID(); 02729 02730 if (FID.isInvalid()) 02731 return SourceLocation(); 02732 02733 return SourceMgr->getLocForStartOfFile(FID); 02734 } 02735 02736 void ASTUnit::PreambleData::countLines() const { 02737 NumLines = 0; 02738 if (empty()) 02739 return; 02740 02741 for (std::vector<char>::const_iterator 02742 I = Buffer.begin(), E = Buffer.end(); I != E; ++I) { 02743 if (*I == '\n') 02744 ++NumLines; 02745 } 02746 if (Buffer.back() != '\n') 02747 ++NumLines; 02748 } 02749 02750 #ifndef NDEBUG 02751 ASTUnit::ConcurrencyState::ConcurrencyState() { 02752 Mutex = new llvm::sys::MutexImpl(/*recursive=*/true); 02753 } 02754 02755 ASTUnit::ConcurrencyState::~ConcurrencyState() { 02756 delete static_cast<llvm::sys::MutexImpl *>(Mutex); 02757 } 02758 02759 void ASTUnit::ConcurrencyState::start() { 02760 bool acquired = static_cast<llvm::sys::MutexImpl *>(Mutex)->tryacquire(); 02761 assert(acquired && "Concurrent access to ASTUnit!"); 02762 } 02763 02764 void ASTUnit::ConcurrencyState::finish() { 02765 static_cast<llvm::sys::MutexImpl *>(Mutex)->release(); 02766 } 02767 02768 #else // NDEBUG 02769 02770 ASTUnit::ConcurrencyState::ConcurrencyState() {} 02771 ASTUnit::ConcurrencyState::~ConcurrencyState() {} 02772 void ASTUnit::ConcurrencyState::start() {} 02773 void ASTUnit::ConcurrencyState::finish() {} 02774 02775 #endif