diff options
Diffstat (limited to 'lib/Frontend/ASTUnit.cpp')
| -rw-r--r-- | lib/Frontend/ASTUnit.cpp | 64 | 
1 files changed, 44 insertions, 20 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 1094e6d089a65..1160df15a9201 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -243,7 +243,8 @@ static unsigned getDeclShowContexts(const NamedDecl *ND,    uint64_t Contexts = 0;    if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||  -      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) { +      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND) || +      isa<TypeAliasTemplateDecl>(ND)) {      // Types can appear in these contexts.      if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))        Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel) @@ -263,8 +264,12 @@ static unsigned getDeclShowContexts(const NamedDecl *ND,        Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);      // In Objective-C, you can only be a subclass of another Objective-C class -    if (isa<ObjCInterfaceDecl>(ND)) +    if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) { +      // Objective-C interfaces can be used in a class property expression. +      if (ID->getDefinition()) +        Contexts |= (1LL << CodeCompletionContext::CCC_Expression);        Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName); +    }      // Deal with tag names.      if (isa<EnumDecl>(ND)) { @@ -542,6 +547,9 @@ private:      // Initialize the ASTContext      Context->InitBuiltinTypes(*Target); +    // Adjust printing policy based on language options. +    Context->setPrintingPolicy(PrintingPolicy(LangOpt)); +      // We didn't have access to the comment options when the ASTContext was      // constructed, so register them now.      Context->getCommentCommandTraits().registerCommentOptions( @@ -962,9 +970,8 @@ public:      }    } -  void HandleMacroDefined(const Token &MacroNameTok, -                          const MacroDirective *MD) override { -    AddDefinedMacroToHash(MacroNameTok, Hash); +  std::unique_ptr<PPCallbacks> createPPCallbacks() override { +    return llvm::make_unique<MacroDefinitionTrackerPPCallbacks>(Hash);    }  private: @@ -1016,6 +1023,19 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,    if (!Invocation)      return true; +  auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation); +  if (OverrideMainBuffer) { +    assert(Preamble && +           "No preamble was built, but OverrideMainBuffer is not null"); +    IntrusiveRefCntPtr<vfs::FileSystem> OldVFS = VFS; +    Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get()); +    if (OldVFS != VFS && FileMgr) { +      assert(OldVFS == FileMgr->getVirtualFileSystem() && +             "VFS passed to Parse and VFS in FileMgr are different"); +      FileMgr = new FileManager(FileMgr->getFileSystemOpts(), VFS); +    } +  } +    // Create the compiler instance to use for building the AST.    std::unique_ptr<CompilerInstance> Clang(        new CompilerInstance(std::move(PCHContainerOps))); @@ -1030,7 +1050,7 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,    llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>      CICleanup(Clang.get()); -  Clang->setInvocation(std::make_shared<CompilerInvocation>(*Invocation)); +  Clang->setInvocation(CCInvocation);    OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();    // Set up diagnostics, capturing any diagnostics that would @@ -1084,9 +1104,6 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,    // If the main file has been overridden due to the use of a preamble,    // make that override happen and introduce the preamble.    if (OverrideMainBuffer) { -    assert(Preamble && "No preamble was built, but OverrideMainBuffer is not null"); -    Preamble->AddImplicitPreamble(Clang->getInvocation(), OverrideMainBuffer.get()); -          // The stored diagnostic has the old source manager in it; update      // the locations to refer into the new source manager. Since we've      // been careful to make sure that the source manager's state @@ -1275,7 +1292,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(      llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(          PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS, -        PCHContainerOps, Callbacks); +        PCHContainerOps, /*StoreInMemory=*/false, Callbacks);      if (NewPreamble) {        Preamble = std::move(*NewPreamble);        PreambleRebuildCounter = 1; @@ -1658,7 +1675,6 @@ ASTUnit *ASTUnit::LoadFromCommandLine(    PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();    PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;    PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors; -  PPOpts.GeneratePreamble = PrecompilePreambleAfterNParses != 0;    PPOpts.SingleFileParseMode = SingleFileParse;    // Override the resources path. @@ -2152,8 +2168,16 @@ void ASTUnit::CodeComplete(    // If the main file has been overridden due to the use of a preamble,    // make that override happen and introduce the preamble.    if (OverrideMainBuffer) { -    assert(Preamble && "No preamble was built, but OverrideMainBuffer is not null"); -    Preamble->AddImplicitPreamble(Clang->getInvocation(), OverrideMainBuffer.get()); +    assert(Preamble && +           "No preamble was built, but OverrideMainBuffer is not null"); + +    auto VFS = FileMgr.getVirtualFileSystem(); +    Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS, +                                  OverrideMainBuffer.get()); +    // FIXME: there is no way to update VFS if it was changed by +    // AddImplicitPreamble as FileMgr is accepted as a parameter by this method. +    // We use on-disk preambles instead and rely on FileMgr's VFS to ensure the +    // PCH files are always readable.      OwnedBuffers.push_back(OverrideMainBuffer.release());    } else {      PreprocessorOpts.PrecompiledPreambleBytes.first = 0; @@ -2395,7 +2419,7 @@ SourceLocation ASTUnit::getLocation(const FileEntry *File,  /// \brief If \arg Loc is a loaded location from the preamble, returns  /// the corresponding local location of the main file, otherwise it returns  /// \arg Loc. -SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) { +SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) const {    FileID PreambleID;    if (SourceMgr)      PreambleID = SourceMgr->getPreambleFileID(); @@ -2416,7 +2440,7 @@ SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) {  /// \brief If \arg Loc is a local location of the main file but inside the  /// preamble chunk, returns the corresponding loaded location from the  /// preamble, otherwise it returns \arg Loc. -SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) { +SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) const {    FileID PreambleID;    if (SourceMgr)      PreambleID = SourceMgr->getPreambleFileID(); @@ -2434,7 +2458,7 @@ SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) {    return Loc;  } -bool ASTUnit::isInPreambleFileID(SourceLocation Loc) { +bool ASTUnit::isInPreambleFileID(SourceLocation Loc) const {    FileID FID;    if (SourceMgr)      FID = SourceMgr->getPreambleFileID(); @@ -2445,7 +2469,7 @@ bool ASTUnit::isInPreambleFileID(SourceLocation Loc) {    return SourceMgr->isInFileID(Loc, FID);  } -bool ASTUnit::isInMainFileID(SourceLocation Loc) { +bool ASTUnit::isInMainFileID(SourceLocation Loc) const {    FileID FID;    if (SourceMgr)      FID = SourceMgr->getMainFileID(); @@ -2456,7 +2480,7 @@ bool ASTUnit::isInMainFileID(SourceLocation Loc) {    return SourceMgr->isInFileID(Loc, FID);  } -SourceLocation ASTUnit::getEndOfPreambleFileID() { +SourceLocation ASTUnit::getEndOfPreambleFileID() const {    FileID FID;    if (SourceMgr)      FID = SourceMgr->getPreambleFileID(); @@ -2467,7 +2491,7 @@ SourceLocation ASTUnit::getEndOfPreambleFileID() {    return SourceMgr->getLocForEndOfFile(FID);  } -SourceLocation ASTUnit::getStartOfMainFileID() { +SourceLocation ASTUnit::getStartOfMainFileID() const {    FileID FID;    if (SourceMgr)      FID = SourceMgr->getMainFileID(); @@ -2543,7 +2567,7 @@ const FileEntry *ASTUnit::getPCHFile() {    return nullptr;  } -bool ASTUnit::isModuleFile() { +bool ASTUnit::isModuleFile() const {    return isMainFileAST() && getLangOpts().isCompilingModule();  }  | 
