Ejemplo n.º 1
0
uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
  uint32_t OldGeneration = CurrentGeneration;

  // Make sure the generation of the topmost external source for the context is
  // incremented. That might not be us.
  auto *P = C.getExternalSource();
  if (P && P != this)
    CurrentGeneration = P->incrementGeneration(C);
  else {
    // FIXME: Only bump the generation counter if the current generation number
    // has been observed?
    if (!++CurrentGeneration)
      llvm::report_fatal_error("generation counter overflowed", false);
  }

  return OldGeneration;
}
Ejemplo n.º 2
0
void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
                              ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
                              ASTContext &C)
{
  if (ExternallyCompleted)
    LoadExternalDefinition();

  if (AllReferencedProtocols.empty() && ReferencedProtocols.empty()) {
    AllReferencedProtocols.set(ExtList, ExtNum, C);
    return;
  }
  
  // Check for duplicate protocol in class's protocol list.
  // This is O(n*m). But it is extremely rare and number of protocols in
  // class or its extension are very few.
  llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
  for (unsigned i = 0; i < ExtNum; i++) {
    bool protocolExists = false;
    ObjCProtocolDecl *ProtoInExtension = ExtList[i];
    for (all_protocol_iterator
          p = all_referenced_protocol_begin(),
          e = all_referenced_protocol_end(); p != e; ++p) {
      ObjCProtocolDecl *Proto = (*p);
      if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
        protocolExists = true;
        break;
      }      
    }
    // Do we want to warn on a protocol in extension class which
    // already exist in the class? Probably not.
    if (!protocolExists)
      ProtocolRefs.push_back(ProtoInExtension);
  }

  if (ProtocolRefs.empty())
    return;

  // Merge ProtocolRefs into class's protocol list;
  for (all_protocol_iterator p = all_referenced_protocol_begin(), 
        e = all_referenced_protocol_end(); p != e; ++p) {
    ProtocolRefs.push_back(*p);
  }

  AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(), C);
}
Ejemplo n.º 3
0
    void HandleTranslationUnit(ASTContext &C) override {
      {
        PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
        if (llvm::TimePassesIsEnabled)
          LLVMIRGeneration.startTimer();

        Gen->HandleTranslationUnit(C);

        if (llvm::TimePassesIsEnabled)
          LLVMIRGeneration.stopTimer();
      }

      // Silently ignore if we weren't initialized for some reason.
      if (!getModule())
        return;

      // Install an inline asm handler so that diagnostics get printed through
      // our diagnostics hooks.
      LLVMContext &Ctx = getModule()->getContext();
      LLVMContext::InlineAsmDiagHandlerTy OldHandler =
        Ctx.getInlineAsmDiagnosticHandler();
      void *OldContext = Ctx.getInlineAsmDiagnosticContext();
      Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);

      LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
          Ctx.getDiagnosticHandler();
      void *OldDiagnosticContext = Ctx.getDiagnosticContext();
      Ctx.setDiagnosticHandler(DiagnosticHandler, this);

      // Link LinkModule into this module if present, preserving its validity.
      for (auto &I : LinkModules) {
        unsigned LinkFlags = I.first;
        CurLinkModule = I.second.get();
        if (Linker::linkModules(*getModule(), std::move(I.second), LinkFlags))
          return;
      }

      EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
                        C.getTargetInfo().getDataLayoutString(),
                        getModule(), Action, AsmOutStream);

      Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);

      Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext);
    }
// Checks if 'typedef' keyword can be removed - we do it only if
// it is the only declaration in a declaration chain.
static bool CheckRemoval(SourceManager &SM, SourceLocation StartLoc,
                         ASTContext &Context) {
  assert(StartLoc.isFileID() && "StartLoc must not be in a macro");
  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(StartLoc);
  StringRef File = SM.getBufferData(LocInfo.first);
  const char *TokenBegin = File.data() + LocInfo.second;
  Lexer DeclLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(),
                  File.begin(), TokenBegin, File.end());

  Token Tok;
  int ParenLevel = 0;
  bool FoundTypedef = false;

  while (!DeclLexer.LexFromRawLexer(Tok) && !Tok.is(tok::semi)) {
    switch (Tok.getKind()) {
    case tok::l_brace:
    case tok::r_brace:
      // This might be the `typedef struct {...} T;` case.
      return false;
    case tok::l_paren:
      ParenLevel++;
      break;
    case tok::r_paren:
      ParenLevel--;
      break;
    case tok::comma:
      if (ParenLevel == 0) {
        // If there is comma and we are not between open parenthesis then it is
        // two or more declarations in this chain.
        return false;
      }
      break;
    case tok::raw_identifier:
      if (Tok.getRawIdentifier() == "typedef") {
        FoundTypedef = true;
      }
      break;
    default:
      break;
    }
  }

  // Sanity check against weird macro cases.
  return FoundTypedef;
}
Ejemplo n.º 5
0
// Constructor for C++ records.
ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
                                 CharUnits size, CharUnits alignment,
                                 bool hasOwnVFPtr, CharUnits vbptroffset,
                                 CharUnits datasize,
                                 const uint64_t *fieldoffsets,
                                 unsigned fieldcount,
                                 CharUnits nonvirtualsize,
                                 CharUnits nonvirtualalign,
                                 CharUnits SizeOfLargestEmptySubobject,
                                 const CXXRecordDecl *PrimaryBase,
                                 bool IsPrimaryBaseVirtual,
                                 const BaseOffsetsMapTy& BaseOffsets,
                                 const VBaseOffsetsMapTy& VBaseOffsets)
  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
    FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
{
  if (FieldCount > 0)  {
    FieldOffsets = new (Ctx) uint64_t[FieldCount];
    memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
  }

  CXXInfo->PrimaryBase.setPointer(PrimaryBase);
  CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
  CXXInfo->NonVirtualSize = nonvirtualsize;
  CXXInfo->NonVirtualAlign = nonvirtualalign;
  CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
  CXXInfo->BaseOffsets = BaseOffsets;
  CXXInfo->VBaseOffsets = VBaseOffsets;
  CXXInfo->HasOwnVFPtr = hasOwnVFPtr;
  CXXInfo->VBPtrOffset = vbptroffset;

#ifndef NDEBUG
    if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
      if (isPrimaryBaseVirtual()) {
        if (Ctx.getTargetInfo().getCXXABI().hasPrimaryVBases()) {
          assert(getVBaseClassOffset(PrimaryBase).isZero() &&
                 "Primary virtual base must be at offset 0!");
        }
      } else {
        assert(getBaseClassOffset(PrimaryBase).isZero() &&
               "Primary base must be at offset 0!");
      }
    }
#endif        
}
Ejemplo n.º 6
0
void ScriptDefn::setCaptures(ASTContext &Context,
                            const Capture *begin,
                            const Capture *end) {
  if (begin == end) {
    NumCaptures = 0;
    Captures = 0;
    return;
  }

  NumCaptures = end - begin;

  // Avoid new Capture[] because we don't want to provide a default
  // constructor.
  size_t allocationSize = NumCaptures * sizeof(Capture);
  void *buffer = Context.Allocate(allocationSize, /*alignment*/sizeof(void*));
  memcpy(buffer, begin, allocationSize);
  Captures = static_cast<Capture*>(buffer);
}
Ejemplo n.º 7
0
void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
  
  TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
  if (MigrateProperty)
    for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end();
         D != DEnd; ++D) {
      if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
        migrateObjCInterfaceDecl(Ctx, CDecl);
      else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D))
        ObjCProtocolDecls.insert(PDecl);
      else if (const ObjCImplementationDecl *ImpDecl =
               dyn_cast<ObjCImplementationDecl>(*D))
        migrateProtocolConformance(Ctx, ImpDecl);
      else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
        DeclContext::decl_iterator N = D;
        ++N;
        if (N != DEnd)
          if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N))
            migrateNSEnumDecl(Ctx, ED, TD);
      }
      // migrate methods which can have instancetype as their result type.
      if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D))
        migrateInstanceType(Ctx, CDecl);
    }
  
  Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
  RewritesReceiver Rec(rewriter);
  Editor->applyRewrites(Rec);

  for (Rewriter::buffer_iterator
        I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
    FileID FID = I->first;
    RewriteBuffer &buf = I->second;
    const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
    assert(file);
    SmallString<512> newText;
    llvm::raw_svector_ostream vecOS(newText);
    buf.write(vecOS);
    vecOS.flush();
    llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
                   StringRef(newText.data(), newText.size()), file->getName());
    SmallString<64> filePath(file->getName());
    FileMgr.FixupRelativePath(filePath);
    Remapper.remap(filePath.str(), memBuf);
  }

  if (IsOutputFile) {
    Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
  } else {
    Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
  }
}
/// Get the returned ObjCObjectPointerType by a method based on the tracked type
/// information, or null pointer when the returned type is not an
/// ObjCObjectPointerType.
static QualType getReturnTypeForMethod(
    const ObjCMethodDecl *Method, ArrayRef<QualType> TypeArgs,
    const ObjCObjectPointerType *SelfType, ASTContext &C) {
  QualType StaticResultType = Method->getReturnType();

  // Is the return type declared as instance type?
  if (StaticResultType == C.getObjCInstanceType())
    return QualType(SelfType, 0);

  // Check whether the result type depends on a type parameter.
  if (!isObjCTypeParamDependent(StaticResultType))
    return QualType();

  QualType ResultType = StaticResultType.substObjCTypeArgs(
      C, TypeArgs, ObjCSubstitutionContext::Result);

  return ResultType;
}
Ejemplo n.º 9
0
TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
                                   QualType Type) {
  Integer.Kind = Integral;
  // Copy the APSInt value into our decomposed form.
  Integer.BitWidth = Value.getBitWidth();
  Integer.IsUnsigned = Value.isUnsigned();
  // If the value is large, we have to get additional memory from the ASTContext
  unsigned NumWords = Value.getNumWords();
  if (NumWords > 1) {
    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
    Integer.pVal = static_cast<uint64_t *>(Mem);
  } else {
    Integer.VAL = Value.getZExtValue();
  }

  Integer.Type = Type.getAsOpaquePtr();
}
Ejemplo n.º 10
0
void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
                               ASTContext &Context) const {
  ID.AddInteger(Kind);
  switch (Kind) {
  case Null:
    break;

  case Type:
    getAsType().Profile(ID);
    break;

  case Declaration:
    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
    break;

  case Template:
    if (TemplateTemplateParmDecl *TTP
          = dyn_cast_or_null<TemplateTemplateParmDecl>(
                                       getAsTemplate().getAsTemplateDecl())) {
      ID.AddBoolean(true);
      ID.AddInteger(TTP->getDepth());
      ID.AddInteger(TTP->getPosition());
    } else {
      ID.AddBoolean(false);
      ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
                      .getAsVoidPointer());
    }
    break;
      
  case Integral:
    getAsIntegral()->Profile(ID);
    getIntegralType().Profile(ID);
    break;

  case Expression:
    getAsExpr()->Profile(ID, Context, true);
    break;

  case Pack:
    ID.AddInteger(Args.NumArgs);
    for (unsigned I = 0; I != Args.NumArgs; ++I)
      Args.Args[I].Profile(ID, Context);
  }
}
Ejemplo n.º 11
0
/// Classify the given Clang enumeration to describe how to import it.
void EnumInfo::classifyEnum(ASTContext &ctx, const clang::EnumDecl *decl,
                            clang::Preprocessor &pp) {
  // Anonymous enumerations simply get mapped to constants of the
  // underlying type of the enum, because there is no way to conjure up a
  // name for the Swift type.
  if (!decl->hasNameForLinkage()) {
    kind = EnumKind::Constants;
    return;
  }

  // First, check for attributes that denote the classification
  if (auto domainAttr = decl->getAttr<clang::NSErrorDomainAttr>()) {
    kind = EnumKind::Enum;
    nsErrorDomain = ctx.AllocateCopy(domainAttr->getErrorDomain()->getName());
    return;
  }

  // Was the enum declared using *_ENUM or *_OPTIONS?
  // FIXME: Use Clang attributes instead of groveling the macro expansion loc.
  auto loc = decl->getLocStart();
  if (loc.isMacroID()) {
    StringRef MacroName = pp.getImmediateMacroName(loc);
    if (MacroName == "CF_ENUM" || MacroName == "__CF_NAMED_ENUM" ||
        MacroName == "OBJC_ENUM" || MacroName == "SWIFT_ENUM" ||
        MacroName == "SWIFT_ENUM_NAMED") {
      kind = EnumKind::Enum;
      return;
    }
    if (MacroName == "CF_OPTIONS" || MacroName == "OBJC_OPTIONS" ||
        MacroName == "SWIFT_OPTIONS") {
      kind = EnumKind::Options;
      return;
    }
  }

  // Hardcode a particular annoying case in the OS X headers.
  if (decl->getName() == "DYLD_BOOL") {
    kind = EnumKind::Enum;
    return;
  }

  // Fall back to the 'Unknown' path.
  kind = EnumKind::Unknown;
}
Ejemplo n.º 12
0
bool FunctionDecl::isExternC(ASTContext &Context) const {
  // In C, any non-static, non-overloadable function has external
  // linkage.
  if (!Context.getLangOptions().CPlusPlus)
    return getStorageClass() != Static && !getAttr<OverloadableAttr>();

  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); 
       DC = DC->getParent()) {
    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
      if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
        return getStorageClass() != Static && 
               !getAttr<OverloadableAttr>();

      break;
    }
  }

  return false;
}
Ejemplo n.º 13
0
void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, 
                                                      unsigned NumArgs,
                                                  const TemplateArgument *Args,
                                              TemplateArgumentLocInfo *ArgInfos,
                                                      SourceLocation Loc) {
  for (unsigned i = 0, e = NumArgs; i != e; ++i) {
    switch (Args[i].getKind()) {
    case TemplateArgument::Null: 
    case TemplateArgument::Declaration:
    case TemplateArgument::Integral:
    case TemplateArgument::Pack:
    case TemplateArgument::Expression:
      // FIXME: Can we do better for declarations and integral values?
      ArgInfos[i] = TemplateArgumentLocInfo();
      break;
      
    case TemplateArgument::Type:
      ArgInfos[i] = TemplateArgumentLocInfo(
                          Context.getTrivialTypeSourceInfo(Args[i].getAsType(), 
                                                           Loc));
      break;
        
    case TemplateArgument::Template:
    case TemplateArgument::TemplateExpansion: {
      NestedNameSpecifierLocBuilder Builder;
      TemplateName Template = Args[i].getAsTemplate();
      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
      
      ArgInfos[i] = TemplateArgumentLocInfo(
                                           Builder.getWithLocInContext(Context),
                                            Loc, 
                                Args[i].getKind() == TemplateArgument::Template
                                            ? SourceLocation()
                                            : Loc);
      break;
    }        
    }
  }
}
Ejemplo n.º 14
0
static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True,
                                     const Expr *False) {
  assert(Ctx.getLangOptions().CPlusPlus &&
         "This is only relevant for C++.");

  // C++ [expr.cond]p2
  //   If either the second or the third operand has type (cv) void, [...]
  //   the result [...] is a prvalue.
  if (True->getType()->isVoidType() || False->getType()->isVoidType())
    return Cl::CL_PRValue;

  // Note that at this point, we have already performed all conversions
  // according to [expr.cond]p3.
  // C++ [expr.cond]p4: If the second and third operands are glvalues of the
  //   same value category [...], the result is of that [...] value category.
  // C++ [expr.cond]p5: Otherwise, the result is a prvalue.
  Cl::Kinds LCl = ClassifyInternal(Ctx, True),
            RCl = ClassifyInternal(Ctx, False);
  return LCl == RCl ? LCl : Cl::CL_PRValue;
}
Ejemplo n.º 15
0
void RewriterASTConsumer::HandleTranslationUnit(ASTContext& Context)
{
    TranslationUnitDecl* D = Context.getTranslationUnitDecl();
    TraverseDecl(D);

    const RewriteBuffer& RewriteBufG =
            TheGpuRewriter.getEditBuffer(TheGpuRewriter.getSourceMgr().getMainFileID());
    RewritenGpuSource = std::string(RewriteBufG.begin(), RewriteBufG.end());

    const RewriteBuffer& RewriteBufC =
            TheCpuRewriter.getEditBuffer(TheCpuRewriter.getSourceMgr().getMainFileID());
    RewritenCpuSource = std::string(RewriteBufC.begin(), RewriteBufC.end());

#ifdef Out
    llvm::errs() << "______________________________ CPU _____________________ \n";
    llvm::errs() << std::string(RewriteBufC.begin(), RewriteBufC.end());
    llvm::errs() << "\n\n______________________________ GPU _____________________ \n";
    llvm::errs() << std::string(RewriteBufG.begin(), RewriteBufG.end());
#endif
}
Ejemplo n.º 16
0
/// \brief Convert the specified DeclSpec to the appropriate type object.
QualType Sema::ActOnTypeName(ASTContext &C, DeclSpec &DS) {
  QualType Result;
  switch (DS.getTypeSpecType()) {
  case DeclSpec::TST_integer:
    Result = C.IntegerTy;
    break;
  case DeclSpec::TST_unspecified: // FIXME: Correct?
  case DeclSpec::TST_real:
    Result = C.RealTy;
    break;
  case DeclSpec::TST_doubleprecision:
    Result = C.DoublePrecisionTy;
    break;
  case DeclSpec::TST_character:
    Result = C.CharacterTy;
    break;
  case DeclSpec::TST_logical:
    Result = C.LogicalTy;
    break;
  case DeclSpec::TST_complex:
    Result = C.ComplexTy;
    break;
  case DeclSpec::TST_struct:
    // FIXME: Finish this.
    break;
  }

  if (!DS.hasAttributes())
    return Result;

  const Type *TypeNode = Result.getTypePtr();
  Qualifiers Quals = Qualifiers::fromOpaqueValue(DS.getAttributeSpecs());
  Quals.setIntentAttr(DS.getIntentSpec());
  Quals.setAccessAttr(DS.getAccessSpec());
  QualType EQs =  C.getExtQualType(TypeNode, Quals, DS.getKindSelector(),
                                   DS.getLengthSelector());
  if (!Quals.hasAttributeSpec(Qualifiers::AS_dimension))
    return EQs;

  return ActOnArraySpec(C, EQs, DS.getDimensions());
}
Ejemplo n.º 17
0
static bool isEmptyARCMTMacroStatement(NullStmt *S,
                                       std::vector<SourceLocation> &MacroLocs,
                                       ASTContext &Ctx) {
  if (!S->hasLeadingEmptyMacro())
    return false;

  SourceLocation SemiLoc = S->getSemiLoc();
  if (SemiLoc.isInvalid() || SemiLoc.isMacroID())
    return false;

  if (MacroLocs.empty())
    return false;

  SourceManager &SM = Ctx.getSourceManager();
  std::vector<SourceLocation>::iterator
    I = std::upper_bound(MacroLocs.begin(), MacroLocs.end(), SemiLoc,
                         BeforeThanCompare<SourceLocation>(SM));
  --I;
  SourceLocation
      AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size());
  assert(AfterMacroLoc.isFileID());

  if (AfterMacroLoc == SemiLoc)
    return true;

  int RelOffs = 0;
  if (!SM.isInSameSLocAddrSpace(AfterMacroLoc, SemiLoc, &RelOffs))
    return false;
  if (RelOffs < 0)
    return false;

  // We make the reasonable assumption that a semicolon after 100 characters
  // means that it is not the next token after our macro. If this assumption
  // fails it is not critical, we will just fail to clear out, e.g., an empty
  // 'if'.
  if (RelOffs - getARCMTMacroName().size() > 100)
    return false;

  SourceLocation AfterMacroSemiLoc = findSemiAfterLocation(AfterMacroLoc, Ctx);
  return AfterMacroSemiLoc == SemiLoc;
}
FullExpr FullExpr::Create(ASTContext &Context, Expr *SubExpr,
                          CXXTemporary **Temporaries, unsigned NumTemporaries) {
  FullExpr E;

  if (!NumTemporaries) {
      E.SubExpr = SubExpr;
      return E;
  }

  unsigned Size = sizeof(FullExpr) 
      + sizeof(CXXTemporary *) * NumTemporaries;

  unsigned Align = llvm::AlignOf<ExprAndTemporaries>::Alignment;
  ExprAndTemporaries *ET = 
      static_cast<ExprAndTemporaries *>(Context.Allocate(Size, Align));

  ET->SubExpr = SubExpr;
  std::copy(Temporaries, Temporaries + NumTemporaries, ET->temps_begin());
    
  return E;
}
Ejemplo n.º 19
0
bool VarDecl::isExternC(ASTContext &Context) const {
  if (!Context.getLangOptions().CPlusPlus)
    return (getDeclContext()->isTranslationUnit() && 
            getStorageClass() != Static) ||
      (getDeclContext()->isFunctionOrMethod() && hasExternalStorage());

  for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit(); 
       DC = DC->getParent()) {
    if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))  {
      if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
        return getStorageClass() != Static;

      break;
    }

    if (DC->isFunctionOrMethod())
      return false;
  }

  return false;
}
Ejemplo n.º 20
0
// Checks if 'typedef' keyword can be removed - we do it only if
// it is the only declaration in a declaration chain.
static bool CheckRemoval(SourceManager &SM, const SourceLocation &LocStart,
                         const SourceLocation &LocEnd, ASTContext &Context,
                         SourceRange &ResultRange) {
  FileID FID = SM.getFileID(LocEnd);
  llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, LocEnd);
  Lexer DeclLexer(SM.getLocForStartOfFile(FID), Context.getLangOpts(),
                  Buffer->getBufferStart(), SM.getCharacterData(LocStart),
                  Buffer->getBufferEnd());
  Token DeclToken;
  bool result = false;
  int parenthesisLevel = 0;

  while (!DeclLexer.LexFromRawLexer(DeclToken)) {
    if (DeclToken.getKind() == tok::TokenKind::l_paren)
      parenthesisLevel++;
    if (DeclToken.getKind() == tok::TokenKind::r_paren)
      parenthesisLevel--;
    if (DeclToken.getKind() == tok::TokenKind::semi)
      break;
    // if there is comma and we are not between open parenthesis then it is
    // two or more declatarions in this chain
    if (parenthesisLevel == 0 && DeclToken.getKind() == tok::TokenKind::comma)
      return false;

    if (DeclToken.isOneOf(tok::TokenKind::identifier,
                          tok::TokenKind::raw_identifier)) {
      auto TokenStr = DeclToken.getRawIdentifier().str();

      if (TokenStr == "typedef") {
        ResultRange =
            SourceRange(DeclToken.getLocation(), DeclToken.getEndLoc());
        result = true;
      }
    }
  }
  // assert if there was keyword 'typedef' in declaration
  assert(result && "No typedef found");

  return result;
}
static Optional<uint64_t> GetCFNumberSize(ASTContext &Ctx, uint64_t i) {
    static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 };

    if (i < kCFNumberCharType)
        return FixedSize[i-1];

    QualType T;

    switch (i) {
    case kCFNumberCharType:
        T = Ctx.CharTy;
        break;
    case kCFNumberShortType:
        T = Ctx.ShortTy;
        break;
    case kCFNumberIntType:
        T = Ctx.IntTy;
        break;
    case kCFNumberLongType:
        T = Ctx.LongTy;
        break;
    case kCFNumberLongLongType:
        T = Ctx.LongLongTy;
        break;
    case kCFNumberFloatType:
        T = Ctx.FloatTy;
        break;
    case kCFNumberDoubleType:
        T = Ctx.DoubleTy;
        break;
    case kCFNumberCFIndexType:
    case kCFNumberNSIntegerType:
    case kCFNumberCGFloatType:
    // FIXME: We need a way to map from names to Type*.
    default:
        return None;
    }

    return Ctx.getTypeSize(T);
}
Ejemplo n.º 22
0
void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context, 
                                                NestedNameSpecifier *Qualifier, 
                                                SourceRange R) {
  Representation = Qualifier;
  
  // Construct bogus (but well-formed) source information for the 
  // nested-name-specifier.
  BufferSize = 0;
  SmallVector<NestedNameSpecifier *, 4> Stack;
  for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
    Stack.push_back(NNS);
  while (!Stack.empty()) {
    NestedNameSpecifier *NNS = Stack.back();
    Stack.pop_back();
    switch (NNS->getKind()) {
      case NestedNameSpecifier::Identifier:
      case NestedNameSpecifier::Namespace:
      case NestedNameSpecifier::NamespaceAlias:
        SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
        break;
        
      case NestedNameSpecifier::TypeSpec:
      case NestedNameSpecifier::TypeSpecWithTemplate: {
        TypeSourceInfo *TSInfo
        = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
                                           R.getBegin());
        SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize, 
                    BufferCapacity);
        break;
      }
        
      case NestedNameSpecifier::Global:
        break;
    }
    
    // Save the location of the '::'.
    SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(), 
                       Buffer, BufferSize, BufferCapacity);
  }
}
Ejemplo n.º 23
0
	string HtDesign::getSourceLine(ASTContext &Context, SourceLocation Loc)
	{
		SourceManager & SM = Context.getSourceManager();

		// Decompose the location into a FID/Offset pair.
		std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
		FileID FID = LocInfo.first;
		unsigned FileOffset = LocInfo.second;

		// Get information about the buffer it points into.
		bool Invalid = false;
		const char *BufStart = SM.getBufferData(FID, &Invalid).data();
		//if (Invalid)
		//return;

		unsigned LineNo = SM.getLineNumber(FID, FileOffset);
		unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
  
		// Arbitrarily stop showing snippets when the line is too long.
		//static const size_t MaxLineLengthToPrint = 4096;
		//if (ColNo > MaxLineLengthToPrint)
		//return;

		// Rewind from the current position to the start of the line.
		const char *TokPtr = BufStart+FileOffset;
		const char *LineStart = TokPtr-ColNo+1; // Column # is 1-based.

		// Compute the line end.  Scan forward from the error position to the end of
		// the line.
		const char *LineEnd = TokPtr;
		while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0')
		++LineEnd;

		// Arbitrarily stop showing snippets when the line is too long.
		//if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint)
		//return;

		// Copy the line of code into an std::string for ease of manipulation.
		return string(LineStart, LineEnd);
	}
Ejemplo n.º 24
0
void AnalysisConsumer::HandleTranslationUnit(ASTContext &contex) { // called when everything is done
		TranslationUnitDecl *tran_unit_ptr = contex.getTranslationUnitDecl();
		AnalysisContextManager context_manager;
		unsigned report_ctr = 0;

		for (DeclContext::decl_iterator iter = tran_unit_ptr->decls_begin(), end = tran_unit_ptr->decls_end(); iter != end; ++iter) {
			// Only handle declarations with bodies
			if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*iter)) {
				if (!FD->isThisDeclarationADefinition())
					continue;
                FD->print(llvm::outs());
				CFG * cfg_ptr = context_manager.getContext(FD)->getCFG();
				if (cfg_ptr) {
//					string error;
//					llvm::raw_fd_ostream os("cfg-file",error);
//					cfg_ptr->print(os,LangOptions());
					AnalyzeFunction(*cfg_ptr, contex, report_ctr);
				}
			}
		}
		report_file_ << setw(6) << report_ctr << " | ";
	}
Ejemplo n.º 25
0
static void 
AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context,
                        CXXIndirectPrimaryBaseSet& Bases) {
  // If the record has a virtual primary base class, add it to our set.
  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
  if (Layout.isPrimaryBaseVirtual())
    Bases.insert(Layout.getPrimaryBase());

  for (const auto &I : RD->bases()) {
    assert(!I.getType()->isDependentType() &&
           "Cannot get indirect primary bases for class with dependent bases.");

    const CXXRecordDecl *BaseDecl =
      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());

    // Only bases with virtual bases participate in computing the
    // indirect primary virtual base classes.
    if (BaseDecl->getNumVBases())
      AddIndirectPrimaryBases(BaseDecl, Context, Bases);
  }

}
Ejemplo n.º 26
0
/// ClassifyDecl - Return the classification of an expression referencing the
/// given declaration.
static Cl::Kinds ClassifyDecl(ASTContext &Ctx, const Decl *D) {
  // C++ [expr.prim.general]p6: The result is an lvalue if the entity is a
  //   function, variable, or data member and a prvalue otherwise.
  // In C, functions are not lvalues.
  // In addition, NonTypeTemplateParmDecl derives from VarDecl but isn't an
  // lvalue unless it's a reference type (C++ [temp.param]p6), so we need to
  // special-case this.

  if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance())
    return Cl::CL_MemberFunction;

  bool islvalue;
  if (const NonTypeTemplateParmDecl *NTTParm =
        dyn_cast<NonTypeTemplateParmDecl>(D))
    islvalue = NTTParm->getType()->isReferenceType();
  else
    islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) ||
      (Ctx.getLangOptions().CPlusPlus &&
        (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)));

  return islvalue ? Cl::CL_LValue : Cl::CL_PRValue;
}
Ejemplo n.º 27
0
    bool HandleTopLevelDecl(DeclGroupRef D) override {
      PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
                                     Context->getSourceManager(),
                                     "LLVM IR generation of declaration");

      // Recurse.
      if (llvm::TimePassesIsEnabled) {
        LLVMIRGenerationRefCount += 1;
        if (LLVMIRGenerationRefCount == 1)
          LLVMIRGeneration.startTimer();
      }

      Gen->HandleTopLevelDecl(D);

      if (llvm::TimePassesIsEnabled) {
        LLVMIRGenerationRefCount -= 1;
        if (LLVMIRGenerationRefCount == 0)
          LLVMIRGeneration.stopTimer();
      }

      return true;
    }
Ejemplo n.º 28
0
Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const {
  assert(!TR->isReferenceType() && "Expressions can't have reference type.");

  Cl::Kinds kind = ClassifyInternal(Ctx, this);
  // C99 6.3.2.1: An lvalue is an expression with an object type or an
  //   incomplete type other than void.
  if (!Ctx.getLangOpts().CPlusPlus) {
    // Thus, no functions.
    if (TR->isFunctionType() || TR == Ctx.OverloadTy)
      kind = Cl::CL_Function;
    // No void either, but qualified void is OK because it is "other than void".
    // Void "lvalues" are classified as addressable void values, which are void
    // expressions whose address can be taken.
    else if (TR->isVoidType() && !TR.hasQualifiers())
      kind = (kind == Cl::CL_LValue ? Cl::CL_AddressableVoid : Cl::CL_Void);
  }

  // Enable this assertion for testing.
  switch (kind) {
  case Cl::CL_LValue: assert(getValueKind() == VK_LValue); break;
  case Cl::CL_XValue: assert(getValueKind() == VK_XValue); break;
  case Cl::CL_Function:
  case Cl::CL_Void:
  case Cl::CL_AddressableVoid:
  case Cl::CL_DuplicateVectorComponents:
  case Cl::CL_MemberFunction:
  case Cl::CL_SubObjCPropertySetting:
  case Cl::CL_ClassTemporary:
  case Cl::CL_ArrayTemporary:
  case Cl::CL_ObjCMessageRValue:
  case Cl::CL_PRValue: assert(getValueKind() == VK_RValue); break;
  }

  Cl::ModifiableType modifiable = Cl::CM_Untested;
  if (Loc)
    modifiable = IsModifiable(Ctx, this, kind, *Loc);
  return Classification(kind, modifiable);
}
  void HandleTranslationUnit(ASTContext &Context) override {
    const auto &SourceMgr = Context.getSourceManager();
    // The file we look for the USR in will always be the main source file.
    const auto Point = SourceMgr.getLocForStartOfFile(
        SourceMgr.getMainFileID()).getLocWithOffset(SymbolOffset);
    if (!Point.isValid())
      return;
    const NamedDecl *FoundDecl = nullptr;
    if (OldName.empty()) {
      FoundDecl = getNamedDeclAt(Context, Point);
    } else {
      FoundDecl = getNamedDeclFor(Context, OldName);
    }
    if (FoundDecl == nullptr) {
      FullSourceLoc FullLoc(Point, SourceMgr);
      errs() << "clang-rename: could not find symbol at "
             << SourceMgr.getFilename(Point) << ":"
             << FullLoc.getSpellingLineNumber() << ":"
             << FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset
             << ").\n";
      return;
    }

    // If the decl is a constructor or destructor, we want to instead take the
    // decl of the parent record.
    if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
      FoundDecl = CtorDecl->getParent();
    else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
      FoundDecl = DtorDecl->getParent();

    // If the decl is in any way relatedpp to a class, we want to make sure we
    // search for the constructor and destructor as well as everything else.
    if (const auto *Record = dyn_cast<CXXRecordDecl>(FoundDecl))
      *USRs = getAllConstructorUSRs(Record);

    USRs->push_back(getUSRForDecl(FoundDecl));
    *SpellingName = FoundDecl->getNameAsString();
  }
Ejemplo n.º 30
0
 virtual bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
   if (E->getReceiverKind() == ObjCMessageExpr::Class) {
     QualType ReceiverType = E->getClassReceiver();
     Selector Sel = E->getSelector();
     string TypeName = ReceiverType.getAsString();
     string SelName = Sel.getAsString();
     if (TypeName == "Observer" && SelName == "observerWithTarget:action:") {
       Expr *Receiver = E->getArg(0)->IgnoreParenCasts();
       ObjCSelectorExpr* SelExpr = cast<ObjCSelectorExpr>(E->getArg(1)->IgnoreParenCasts());
       Selector Sel = SelExpr->getSelector();
       if (const ObjCObjectPointerType *OT = Receiver->getType()->getAs<ObjCObjectPointerType>()) {
         ObjCInterfaceDecl *decl = OT->getInterfaceDecl();
         if (! decl->lookupInstanceMethod(Sel)) {
           errs() << "Warning: class " << TypeName << " does not implement selector " << Sel.getAsString() << "\n";
           SourceLocation Loc = E->getExprLoc();
           PresumedLoc PLoc = astContext->getSourceManager().getPresumedLoc(Loc);
           errs() << "in " << PLoc.getFilename() << " <" << PLoc.getLine() << ":" << PLoc.getColumn() << ">\n";
         }
       }
     }
   }
   return true;
 }