Esempio n. 1
0
 void DeclCollector::AddedCXXImplicitMember(const CXXRecordDecl *RD,
                                            const Decl *D) {
   assert(D->isImplicit());
   // We need to mark the decls coming from the modules
   if (comesFromASTReader(RD) || comesFromASTReader(D)) {
     Decl* implicitD = const_cast<Decl*>(D);
     implicitD->addAttr(UsedAttr::CreateImplicit(implicitD->getASTContext()));
   }
 }
Esempio n. 2
0
  bool DeclCollector::HandleTopLevelDecl(DeclGroupRef DGR) {
    // if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
    // pipe it directly to codegen.
    if (comesFromASTReader(DGR)) {
      if (m_CodeGen) {
        for (DeclGroupRef::iterator I = DGR.begin(), E = DGR.end();
             I != E; ++I) {
          if (NamespaceDecl* ND = dyn_cast<NamespaceDecl>(*I)) {
            for (NamespaceDecl::decl_iterator IN = ND->decls_begin(),
                   EN = ND->decls_end(); IN != EN; ++IN)
              // Recurse over decls inside the namespace, like
              // CodeGenModule::EmitNamespace() does.
              HandleTopLevelDecl(DeclGroupRef(*IN));
          } else {
            if (!shouldIgnoreDeclFromASTReader(*I)) {
              m_CodeGen->HandleTopLevelDecl(DeclGroupRef(*I));
            }
            // FIXME: once modules are there this is not needed anymore.
            // it is used to simulate modules and the ASTDeserializationListener
            // for sources that are included to describe the library that was
            // built from the sources (ACLiC).
            if (!(*I)->isFromASTFile() && m_Interp->getASTDeserializationListener())
              m_Interp->getASTDeserializationListener()->DeclRead(0, *I);
          }
        }
      }
      return true;
    }

    Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleTopLevelDecl);
    m_CurTransaction->append(DCI);
    return true;
  }
Esempio n. 3
0
 void DeclCollector::HandleInterestingDecl(DeclGroupRef DGR) {
   assert(m_CurTransaction && "Missing transction");
   Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleInterestingDecl);
   m_CurTransaction->append(DCI);
   if (m_Consumer
       && (!comesFromASTReader(DGR) || !shouldIgnore(*DGR.begin())))
     m_Consumer->HandleTopLevelDecl(DGR);
 }
Esempio n. 4
0
 void DeclCollector::HandleCXXStaticMemberVarInstantiation(VarDecl *D) {
   assert(m_CurTransaction && "Missing transction");
   Transaction::DelayCallInfo DCI(DeclGroupRef(D),
                                  Transaction::kCCIHandleCXXStaticMemberVarInstantiation);
   m_CurTransaction->append(DCI);
   if (m_Consumer
       && (!comesFromASTReader(DeclGroupRef(D))
           || !shouldIgnore(D)))
   m_Consumer->HandleCXXStaticMemberVarInstantiation(D);
 }
Esempio n. 5
0
 void DeclCollector::HandleTagDeclDefinition(TagDecl* TD) {
   assert(m_CurTransaction && "Missing transction");
   Transaction::DelayCallInfo DCI(DeclGroupRef(TD),
                                  Transaction::kCCIHandleTagDeclDefinition);
   m_CurTransaction->append(DCI);
   if (m_Consumer
       && (!comesFromASTReader(DeclGroupRef(TD))
           || !shouldIgnore(TD)))
     m_Consumer->HandleTagDeclDefinition(TD);
 }
Esempio n. 6
0
  void DeclCollector::HandleInterestingDecl(DeclGroupRef DGR) {
    // if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
    // pipe it directly to codegen.
    if (comesFromASTReader(DGR)) {
      HandleTopLevelDecl(DGR);
      return;
    }

    Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleInterestingDecl);
    m_CurTransaction->append(DCI);
  }
Esempio n. 7
0
 void DeclCollector::CompleteTentativeDefinition(VarDecl* VD) {
   assert(m_CurTransaction && "Missing transction");
   // C has tentative definitions which we might need to deal with when running
   // in C mode.
   Transaction::DelayCallInfo DCI(DeclGroupRef(VD),
                                  Transaction::kCCICompleteTentativeDefinition);
   m_CurTransaction->append(DCI);
   if (m_Consumer
       && (!comesFromASTReader(DeclGroupRef(VD))
           || !shouldIgnore(VD)))
   m_Consumer->CompleteTentativeDefinition(VD);
 }
Esempio n. 8
0
  void DeclCollector::HandleTagDeclDefinition(TagDecl* TD) {
    // if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
    // pipe it directly to codegen.
    if (comesFromASTReader(DeclGroupRef(TD))) {
      if (m_CodeGen)
        m_CodeGen->HandleTagDeclDefinition(TD);
      return;
    }

    Transaction::DelayCallInfo DCI(DeclGroupRef(TD), 
                                   Transaction::kCCIHandleTagDeclDefinition);
    m_CurTransaction->append(DCI);    
  }
Esempio n. 9
0
  void DeclCollector::HandleCXXStaticMemberVarInstantiation(VarDecl *D) {
    // if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
    // pipe it directly to codegen.
    if (comesFromASTReader(DeclGroupRef(D))) {
      if (m_CodeGen && !shouldIgnoreDeclFromASTReader(D))
          m_CodeGen->HandleCXXStaticMemberVarInstantiation(D);
      return;
    }

    Transaction::DelayCallInfo DCI(DeclGroupRef(D),
                                   Transaction::kCCIHandleCXXStaticMemberVarInstantiation);
    m_CurTransaction->append(DCI);
  }
Esempio n. 10
0
  void DeclCollector::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {
    // if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
    // pipe it directly to codegen.
    if (comesFromASTReader(DeclGroupRef(D))) {
      if (m_CodeGen)
        m_CodeGen->HandleCXXImplicitFunctionInstantiation(D);
      return;
    }

    Transaction::DelayCallInfo DCI(DeclGroupRef(D),
                                   Transaction::kCCIHandleCXXImplicitFunctionInstantiation);
    m_CurTransaction->append(DCI);
  }
Esempio n. 11
0
  void Transaction::forceAppend(DelayCallInfo DCI) {
    assert(!DCI.m_DGR.isNull() && "Appending null DGR?!");
    assert((getState() == kCollecting || getState() == kCompleted)
           && "Must not be");

    bool checkForWrapper = !m_WrapperFD;

#ifndef NDEBUG
    // Check for duplicates
    for (size_t i = 0, e = m_DeclQueue.size(); i < e; ++i) {
      DelayCallInfo &oldDCI (m_DeclQueue[i]);
      // FIXME: This is possible bug in clang, which will instantiate one and 
      // the same CXXStaticMemberVar several times. This happens when there are
      // two dependent expressions and the first uses another declaration from 
      // the redeclaration chain. This will force Sema in to instantiate the
      // definition (usually the most recent decl in the chain) and then the
      // second expression might referece the definition (which was already)
      // instantiated, but Sema seems not to keep track of these kinds of
      // instantiations, even though the points of instantiation are the same!
      //
      // This should be investigated further when we merge with newest clang.
      // This is triggered by running the roottest: ./root/io/newstl
      if (oldDCI.m_Call == kCCIHandleCXXStaticMemberVarInstantiation)
        continue;
      // It is possible to have duplicate calls to HandleVTable with the same
      // declaration, because each time Sema believes a vtable is used it emits
      // that callback. 
      // For reference (clang::CodeGen::CodeGenModule::EmitVTable).
      if (oldDCI.m_Call != kCCIHandleVTable)
        assert(oldDCI != DCI && "Duplicates?!");
    }
    // We want to assert there is only one wrapper per transaction.
    checkForWrapper = true;
#endif
    
    // register the wrapper if any.
    if (checkForWrapper && !DCI.m_DGR.isNull() && DCI.m_DGR.isSingleDecl()) {
      if (FunctionDecl* FD = dyn_cast<FunctionDecl>(DCI.m_DGR.getSingleDecl())){
        if (checkForWrapper && utils::Analyze::IsWrapper(FD)) {
          assert(!m_WrapperFD && "Two wrappers in one transaction?");
          m_WrapperFD = FD;
        }
      }
    }
    
    if (comesFromASTReader(DCI.m_DGR))
      m_DeserializedDeclQueue.push_back(DCI);
    else
      m_DeclQueue.push_back(DCI);
  }
Esempio n. 12
0
  void DeclCollector::HandleVTable(CXXRecordDecl* RD) {
    assert(m_CurTransaction && "Missing transction");
    Transaction::DelayCallInfo DCI(DeclGroupRef(RD),
                                   Transaction::kCCIHandleVTable);
    m_CurTransaction->append(DCI);

    if (m_Consumer
        && (!comesFromASTReader(DeclGroupRef(RD))
            || !shouldIgnore(RD)))
      m_Consumer->HandleVTable(RD);
    // Intentional no-op. It comes through Sema::DefineUsedVTables, which
    // comes either Sema::ActOnEndOfTranslationUnit or while instantiating a
    // template. In our case we will do it on transaction commit, without
    // keeping track of used vtables, because we have cases where we bypass the
    // clang/AST and directly ask the module so that we have to generate
    // everything without extra smartness.
  }
Esempio n. 13
0
  bool DeclCollector::HandleTopLevelDecl(DeclGroupRef DGR) {
    if (!Transform(DGR))
      return false;

    if (DGR.isNull())
      return true;

    assert(m_CurTransaction && "Missing transction");
    Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleTopLevelDecl);
    m_CurTransaction->append(DCI);
    if (!m_Consumer
        || getTransaction()->getIssuedDiags() == Transaction::kErrors)
      return true;

    if (comesFromASTReader(DGR)) {
      for (DeclGroupRef::iterator DI = DGR.begin(), DE = DGR.end();
           DI != DE; ++DI) {
        DeclGroupRef SplitDGR(*DI);
        // FIXME: The special namespace treatment (not sending itself to
        // CodeGen, but only its content - if the contained decl should be
        // emitted) works around issue with the static initialization when
        // having a PCH and loading a library. We don't want to generate
        // code for the static that will come through the library.
        //
        // This will be fixed with the clang::Modules. Make sure we remember.
        // assert(!getCI()->getLangOpts().Modules && "Please revisit!");
        if (NamespaceDecl* ND = dyn_cast<NamespaceDecl>(*DI)) {
          for (NamespaceDecl::decl_iterator NDI = ND->decls_begin(),
               EN = ND->decls_end(); NDI != EN; ++NDI) {
            // Recurse over decls inside the namespace, like
            // CodeGenModule::EmitNamespace() does.
            if (!shouldIgnore(*NDI))
              m_Consumer->HandleTopLevelDecl(DeclGroupRef(*NDI));
          }
        } else if (!shouldIgnore(*DI)) {
          m_Consumer->HandleTopLevelDecl(DeclGroupRef(*DI));
        }
        continue;
      }
    } else {
      m_Consumer->HandleTopLevelDecl(DGR);
    }
    return true;
  }
Esempio n. 14
0
  void DeclCollector::HandleVTable(CXXRecordDecl* RD, bool DefinitionRequired) {
    // if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
    // pipe it directly to codegen.
    if (comesFromASTReader(DeclGroupRef(RD))) {
      // FIXME: when is the vtable part of the library?
      if (m_CodeGen)
        m_CodeGen->HandleVTable(RD, DefinitionRequired);
      return;
    }

    Transaction::DelayCallInfo DCI(DeclGroupRef(RD),
                                   Transaction::kCCIHandleVTable);
    m_CurTransaction->append(DCI);    

    // Intentional no-op. It comes through Sema::DefineUsedVTables, which
    // comes either Sema::ActOnEndOfTranslationUnit or while instantiating a
    // template. In our case we will do it on transaction commit, without 
    // keeping track of used vtables, because we have cases where we bypass the
    // clang/AST and directly ask the module so that we have to generate 
    // everything without extra smartness.
  }
Esempio n. 15
0
 bool DeclCollector::comesFromASTReader(const Decl* D) const {
   // The operation is const but clang::DeclGroupRef doesn't allow us to
   // express it.
   return comesFromASTReader(DeclGroupRef(const_cast<Decl*>(D)));
 }