Esempio n. 1
0
// Do we know that we will eventually codegen the given function?
static bool IsKnownEmitted(Sema &S, FunctionDecl *FD) {
  // Templates are emitted when they're instantiated.
  if (FD->isDependentContext())
    return false;

  // When compiling for device, host functions are never emitted.  Similarly,
  // when compiling for host, device and global functions are never emitted.
  // (Technically, we do emit a host-side stub for global functions, but this
  // doesn't count for our purposes here.)
  Sema::CUDAFunctionTarget T = S.IdentifyCUDATarget(FD);
  if (S.getLangOpts().CUDAIsDevice && T == Sema::CFT_Host)
    return false;
  if (!S.getLangOpts().CUDAIsDevice &&
      (T == Sema::CFT_Device || T == Sema::CFT_Global))
    return false;

  // Check whether this function is externally visible -- if so, it's
  // known-emitted.
  //
  // We have to check the GVA linkage of the function's *definition* -- if we
  // only have a declaration, we don't know whether or not the function will be
  // emitted, because (say) the definition could include "inline".
  FunctionDecl *Def = FD->getDefinition();

  if (Def &&
      !isDiscardableGVALinkage(S.getASTContext().GetGVALinkageForFunction(Def)))
    return true;

  // Otherwise, the function is known-emitted if it's in our set of
  // known-emitted functions.
  return S.DeviceKnownEmittedFns.count(FD) > 0;
}
Esempio n. 2
0
    bool VisitCompoundStmt(CompoundStmt* CS) {
      for(CompoundStmt::body_iterator I = CS->body_begin(), E = CS->body_end();
          I != E; ++I) {
        if (!isa<BinaryOperator>(*I))
          continue;

        const BinaryOperator* BinOp = cast<BinaryOperator>(*I);
        if (isAutoCandidate(BinOp)) {
          ASTContext& C = m_Sema->getASTContext();
          VarDecl* VD 
            = cast<VarDecl>(cast<DeclRefExpr>(BinOp->getLHS())->getDecl());
          TypeSourceInfo* ResTSI = 0;
          TypeSourceInfo* TrivialTSI 
            = C.getTrivialTypeSourceInfo(VD->getType());
          Expr* RHS = BinOp->getRHS();
          m_Sema->DeduceAutoType(TrivialTSI, RHS, ResTSI);
          VD->setTypeSourceInfo(ResTSI);
          VD->setType(ResTSI->getType());
          VD->setInit(RHS);
          Sema::DeclGroupPtrTy VDPtrTy = m_Sema->ConvertDeclToDeclGroup(VD);
          // Transform the AST into a "sane" state. Replace the binary operator
          // with decl stmt, because the binop semantically is a decl with init.
          StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, BinOp->getLocStart(), 
                                                BinOp->getLocEnd());
          assert(!DS.isInvalid() && "Invalid DeclStmt.");
          *I = DS.take();
        }
      }
      return true; // returning false will abort the in-depth traversal.
    }
 ~InterpreterExternalSemaSource() {
   // FIXME: Another gross hack due to the missing multiplexing AST external
   // source see Interpreter::setCallbacks.
   if (m_Sema) {
     ASTContext& C = m_Sema->getASTContext();
     // tell the owning ptr to not delete it, the callbacks will delete it.
     if (C.ExternalSource.get() == this)
       C.ExternalSource.resetWithoutRelease();
   }
 }
Esempio n. 4
0
static void SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
  // Don't issue a fixit if there is already an initializer.
  if (VD->getInit())
    return;

  // Suggest possible initialization (if any).
  const char *initialization = 0;
  QualType VariableTy = VD->getType().getCanonicalType();

  if (VariableTy->isObjCObjectPointerType() ||
      VariableTy->isBlockPointerType()) {
    // Check if 'nil' is defined.
    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil")))
      initialization = " = nil";
    else
      initialization = " = 0";
  }
  else if (VariableTy->isRealFloatingType())
    initialization = " = 0.0";
  else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus)
    initialization = " = false";
  else if (VariableTy->isEnumeralType())
    return;
  else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) {
    // Check if 'NULL' is defined.
    if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL")))
      initialization = " = NULL";
    else
      initialization = " = 0";
  }
  else if (VariableTy->isScalarType())
    initialization = " = 0";

  if (initialization) {
    SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
    S.Diag(loc, diag::note_var_fixit_add_initialization)
      << FixItHint::CreateInsertion(loc, initialization);
  }
}
Esempio n. 5
0
 void Fix(CompoundStmt* CS) {
   if (!CS->size())
     return;
   typedef llvm::SmallVector<Stmt*, 32> Statements;
   Statements Stmts;
   Stmts.append(CS->body_begin(), CS->body_end());
   for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) {
     if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) {
       Sema::DeclGroupPtrTy VDPtrTy 
         = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl());
       StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, 
                                             m_FoundDRE->getLocStart(), 
                                             m_FoundDRE->getLocEnd());
       assert(!DS.isInvalid() && "Invalid DeclStmt.");
       I = Stmts.insert(I, DS.take());
       m_HandledDecls.insert(m_FoundDRE->getDecl());
     }
   }
   CS->setStmts(m_Sema->getASTContext(), Stmts.data(), Stmts.size());
 }
Esempio n. 6
0
  void IncrementalParser::Initialize() {
    if (hasCodeGenerator())
      getCodeGenerator()->Initialize(getCI()->getASTContext());

    CompilationOptions CO;
    CO.DeclarationExtraction = 0;
    CO.ValuePrinting = CompilationOptions::VPDisabled;
    CO.CodeGeneration = hasCodeGenerator();

    // pull in PCHs
    const std::string& PCHFileName
      = m_CI->getInvocation ().getPreprocessorOpts().ImplicitPCHInclude;
    if (!PCHFileName.empty()) {
      
      Transaction* CurT = beginTransaction(CO);
      m_CI->createPCHExternalASTSource(PCHFileName,
                                       true /*DisablePCHValidation*/,
                                       true /*AllowPCHWithCompilerErrors*/,
                                       0 /*DeserializationListener*/);
      Transaction* EndedT = endTransaction(CurT);
      commitTransaction(EndedT);
    }

    Transaction* CurT = beginTransaction(CO);
    Sema* TheSema = &m_CI->getSema();
    m_Parser.reset(new Parser(m_CI->getPreprocessor(), *TheSema,
                              false /*skipFuncBodies*/));
    m_CI->getPreprocessor().EnterMainSourceFile();
    // Initialize the parser after we have entered the main source file.
    m_Parser->Initialize();
    // Perform initialization that occurs after the parser has been initialized
    // but before it parses anything. Initializes the consumers too.
    TheSema->Initialize();

    ExternalASTSource *External = TheSema->getASTContext().getExternalSource();
    if (External)
      External->StartTranslationUnit(m_Consumer);

    Transaction* EndedT = endTransaction(CurT);
    commitTransaction(EndedT);
  }
Esempio n. 7
0
// Do we know that we will eventually codegen the given function?
static bool IsKnownEmitted(Sema &S, FunctionDecl *FD) {
  // Templates are emitted when they're instantiated.
  if (FD->isDependentContext())
    return false;

  // When compiling for device, host functions are never emitted.  Similarly,
  // when compiling for host, device and global functions are never emitted.
  // (Technically, we do emit a host-side stub for global functions, but this
  // doesn't count for our purposes here.)
  Sema::CUDAFunctionTarget T = S.IdentifyCUDATarget(FD);
  if (S.getLangOpts().CUDAIsDevice && T == Sema::CFT_Host)
    return false;
  if (!S.getLangOpts().CUDAIsDevice &&
      (T == Sema::CFT_Device || T == Sema::CFT_Global))
    return false;

  // Externally-visible and similar functions are always emitted.
  if (!isDiscardableGVALinkage(S.getASTContext().GetGVALinkageForFunction(FD)))
    return true;

  // Otherwise, the function is known-emitted if it's in our set of
  // known-emitted functions.
  return S.CUDAKnownEmittedFns.count(FD) > 0;
}
 PointerCheckInjector(Sema& S) : m_Sema(S), m_Context(S.getASTContext()),
 m_clingthrowIfInvalidPointerCache(0) {}
    // Deal with all the call expr in the transaction.
    bool VisitCallExpr(CallExpr* TheCall) {
      if (FunctionDecl* FDecl = TheCall->getDirectCallee()) {
        std::bitset<32> ArgIndexs;
        for (FunctionDecl::redecl_iterator RI = FDecl->redecls_begin(),
             RE = FDecl->redecls_end(); RI != RE; ++RI) {
          for (specific_attr_iterator<NonNullAttr>
               I = RI->specific_attr_begin<NonNullAttr>(),
               E = RI->specific_attr_end<NonNullAttr>(); I != E; ++I) {
            NonNullAttr *NonNull = *I;

            // Store all the null attr argument's index into "ArgIndexs".
            for (NonNullAttr::args_iterator i = NonNull->args_begin(),
                 e = NonNull->args_end(); i != e; ++i) {

              // Get the argument with the nonnull attribute.
              const Expr* Arg = TheCall->getArg(*i);

              // Check whether we can get the argument'value. If the argument is
              // not null, then ignore this argument and continue to deal with the
              // next argument with the nonnull attribute.ArgIndexs.set(*i);
              bool Result;
              ASTContext& Context = m_Sema->getASTContext();
              if (Arg->EvaluateAsBooleanCondition(Result, Context) && Result) {
                continue;
              }
              ArgIndexs.set(*i);
            }
            break;
          }
        }

        if (ArgIndexs.any()) {

          // Get the function decl's name.
          std::string FName = getMangledName(FDecl);

          // Store the function decl's name into the vector.
          m_NonNullDeclNames.push_back(FName);

          // Store the function decl's name with its null attr args' indexes
          // into the map.
          m_NonNullArgIndexs.insert(std::make_pair(FName, ArgIndexs));
        }

        // FIXME: For now we will only work/check on declarations that are not
        // deserialized. We want to avoid our null deref transaformer to 
        // deserialize all the contents of a PCH/PCM.
        // We have to think of a better way to find the annotated 
        // declarations, without that to cause too much deserialization.
        Stmt* S = (FDecl->isFromASTFile()) ? 0 : FDecl->getBody();
        if (S) {
          for (Stmt::child_iterator II = S->child_begin(), EE = S->child_end();
               II != EE; ++II) {
            CallExpr* child = dyn_cast<CallExpr>(*II);
            if (child && child->getDirectCallee() != FDecl)
              VisitCallExpr(child);
          }
        }
      }
      return true; // returning false will abort the in-depth traversal.
    }
Esempio n. 10
0
void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
  // Collect global stats on Decls/Stmts (until we have a module streamer).
  if (PrintStats) {
    Decl::EnableStatistics();
    Stmt::EnableStatistics();
  }

  // Also turn on collection of stats inside of the Sema object.
  bool OldCollectStats = PrintStats;
  std::swap(OldCollectStats, S.CollectStats);

  ASTConsumer *Consumer = &S.getASTConsumer();

  OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S,
                                       SkipFunctionBodies));
  Parser &P = *ParseOP.get();

  PrettyStackTraceParserEntry CrashInfo(P);

  // Recover resources if we crash before exiting this method.
  llvm::CrashRecoveryContextCleanupRegistrar<Parser>
    CleanupParser(ParseOP.get());

  S.getPreprocessor().EnterMainSourceFile();
  P.Initialize();
  S.Initialize();

  // C11 6.9p1 says translation units must have at least one top-level
  // declaration. C++ doesn't have this restriction. We also don't want to
  // complain if we have a precompiled header, although technically if the PCH
  // is empty we should still emit the (pedantic) diagnostic.
  Parser::DeclGroupPtrTy ADecl;
  ExternalASTSource *External = S.getASTContext().getExternalSource();
  if (External)
    External->StartTranslationUnit(Consumer);

  if (P.ParseTopLevelDecl(ADecl)) {
    if (!External && !S.getLangOpts().CPlusPlus)
      P.Diag(diag::ext_empty_translation_unit);
  } else {
    do {
      // If we got a null return and something *was* parsed, ignore it.  This
      // is due to a top-level semicolon, an action override, or a parse error
      // skipping something.
      if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
	return;
    } while (!P.ParseTopLevelDecl(ADecl));
  }

  // Process any TopLevelDecls generated by #pragma weak.
  for (SmallVector<Decl*,2>::iterator
       I = S.WeakTopLevelDecls().begin(),
       E = S.WeakTopLevelDecls().end(); I != E; ++I)
    Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
  
  Consumer->HandleTranslationUnit(S.getASTContext());

  std::swap(OldCollectStats, S.CollectStats);
  if (PrintStats) {
    llvm::errs() << "\nSTATISTICS:\n";
    P.getActions().PrintStats();
    S.getASTContext().PrintStats();
    Decl::PrintStats();
    Stmt::PrintStats();
    Consumer->PrintStats();
  }
}
Esempio n. 11
0
void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
  // Collect global stats on Decls/Stmts (until we have a module streamer).
  if (PrintStats) {
    Decl::EnableStatistics();
    Stmt::EnableStatistics();
  }

  // Also turn on collection of stats inside of the Sema object.
  bool OldCollectStats = PrintStats;
  std::swap(OldCollectStats, S.CollectStats);

  // Initialize the template instantiation observer chain.
  // FIXME: See note on "finalize" below.
  initialize(S.TemplateInstCallbacks, S);

  ASTConsumer *Consumer = &S.getASTConsumer();

  std::unique_ptr<Parser> ParseOP(
      new Parser(S.getPreprocessor(), S, SkipFunctionBodies));
  Parser &P = *ParseOP.get();

  llvm::CrashRecoveryContextCleanupRegistrar<const void, ResetStackCleanup>
      CleanupPrettyStack(llvm::SavePrettyStackState());
  PrettyStackTraceParserEntry CrashInfo(P);

  // Recover resources if we crash before exiting this method.
  llvm::CrashRecoveryContextCleanupRegistrar<Parser>
    CleanupParser(ParseOP.get());

  S.getPreprocessor().EnterMainSourceFile();
  P.Initialize();

  Parser::DeclGroupPtrTy ADecl;
  ExternalASTSource *External = S.getASTContext().getExternalSource();
  if (External)
    External->StartTranslationUnit(Consumer);

  for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF;
       AtEOF = P.ParseTopLevelDecl(ADecl)) {
    // If we got a null return and something *was* parsed, ignore it.  This
    // is due to a top-level semicolon, an action override, or a parse error
    // skipping something.
    if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
      return;
  }

  // Process any TopLevelDecls generated by #pragma weak.
  for (Decl *D : S.WeakTopLevelDecls())
    Consumer->HandleTopLevelDecl(DeclGroupRef(D));
  
  Consumer->HandleTranslationUnit(S.getASTContext());

  // Finalize the template instantiation observer chain.
  // FIXME: This (and init.) should be done in the Sema class, but because
  // Sema does not have a reliable "Finalize" function (it has a
  // destructor, but it is not guaranteed to be called ("-disable-free")).
  // So, do the initialization above and do the finalization here:
  finalize(S.TemplateInstCallbacks, S);

  std::swap(OldCollectStats, S.CollectStats);
  if (PrintStats) {
    llvm::errs() << "\nSTATISTICS:\n";
    P.getActions().PrintStats();
    S.getASTContext().PrintStats();
    Decl::PrintStats();
    Stmt::PrintStats();
    Consumer->PrintStats();
  }
}
Esempio n. 12
0
  bool
  IncrementalParser::Initialize(llvm::SmallVectorImpl<ParseResultTransaction>&
                                result, bool isChildInterpreter) {
    m_TransactionPool.reset(new TransactionPool);
    if (hasCodeGenerator())
      getCodeGenerator()->Initialize(getCI()->getASTContext());

    CompilationOptions CO = m_Interpreter->makeDefaultCompilationOpts();
    Transaction* CurT = beginTransaction(CO);
    Preprocessor& PP = m_CI->getPreprocessor();
    DiagnosticsEngine& Diags = m_CI->getSema().getDiagnostics();

    // Pull in PCH.
    const std::string& PCHFileName
      = m_CI->getInvocation().getPreprocessorOpts().ImplicitPCHInclude;
    if (!PCHFileName.empty()) {
      Transaction* PchT = beginTransaction(CO);
      DiagnosticErrorTrap Trap(Diags);
      m_CI->createPCHExternalASTSource(PCHFileName,
                                       true /*DisablePCHValidation*/,
                                       true /*AllowPCHWithCompilerErrors*/,
                                       0 /*DeserializationListener*/,
                                       true /*OwnsDeserializationListener*/);
      result.push_back(endTransaction(PchT));
      if (Trap.hasErrorOccurred()) {
        result.push_back(endTransaction(CurT));
        return false;
      }
    }

    addClingPragmas(*m_Interpreter);

    // Must happen after attaching the PCH, else PCH elements will end up
    // being lexed.
    PP.EnterMainSourceFile();

    Sema* TheSema = &m_CI->getSema();
    m_Parser.reset(new Parser(PP, *TheSema, false /*skipFuncBodies*/));

    // Initialize the parser after PP has entered the main source file.
    m_Parser->Initialize();

    ExternalASTSource *External = TheSema->getASTContext().getExternalSource();
    if (External)
      External->StartTranslationUnit(m_Consumer);

    // Start parsing the "main file" to warm up lexing (enter caching lex mode
    // for ParseInternal()'s call EnterSourceFile() to make sense.
    while (!m_Parser->ParseTopLevelDecl()) {}

    // If I belong to the parent Interpreter, am using C++, and -noruntime
    // wasn't given on command line, then #include <new> and check ABI
    if (!isChildInterpreter && m_CI->getLangOpts().CPlusPlus &&
        !m_Interpreter->getOptions().NoRuntime) {
      // <new> is needed by the ValuePrinter so it's a good thing to include it.
      // We need to include it to determine the version number of the standard
      // library implementation.
      ParseInternal("#include <new>");
      // That's really C++ ABI compatibility. C has other problems ;-)
      CheckABICompatibility(*m_Interpreter);
    }

    // DO NOT commit the transactions here: static initialization in these
    // transactions requires gCling through local_cxa_atexit(), but that has not
    // been defined yet!
    ParseResultTransaction PRT = endTransaction(CurT);
    result.push_back(PRT);
    return true;
  }