bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
  assert(UseUnqualifiedMatch);
  if (Node.getIdentifier()) {
    // Simple name.
    return Name == Node.getName();
  }
  if (Node.getDeclName()) {
    // Name needs to be constructed.
    llvm::SmallString<128> NodeName;
    llvm::raw_svector_ostream OS(NodeName);
    Node.printName(OS);
    return Name == OS.str();
  }
  return false;
}
bool Sema::CheckParameterPacksForExpansion(
    SourceLocation EllipsisLoc, SourceRange PatternRange,
    ArrayRef<UnexpandedParameterPack> Unexpanded,
    const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
    bool &RetainExpansion, Optional<unsigned> &NumExpansions) {
  ShouldExpand = true;
  RetainExpansion = false;
  std::pair<IdentifierInfo *, SourceLocation> FirstPack;
  bool HaveFirstPack = false;

  for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
                                                 end = Unexpanded.end();
                                                  i != end; ++i) {
    // Compute the depth and index for this parameter pack.
    unsigned Depth = 0, Index = 0;
    IdentifierInfo *Name;
    bool IsFunctionParameterPack = false;

    if (const TemplateTypeParmType *TTP
        = i->first.dyn_cast<const TemplateTypeParmType *>()) {
      Depth = TTP->getDepth();
      Index = TTP->getIndex();
      Name = TTP->getIdentifier();
    } else {
      NamedDecl *ND = i->first.get<NamedDecl *>();
      if (isa<ParmVarDecl>(ND))
        IsFunctionParameterPack = true;
      else
        std::tie(Depth, Index) = getDepthAndIndex(ND);

      Name = ND->getIdentifier();
    }

    // Determine the size of this argument pack.
    unsigned NewPackSize;
    if (IsFunctionParameterPack) {
      // Figure out whether we're instantiating to an argument pack or not.
      typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;

      llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
        = CurrentInstantiationScope->findInstantiationOf(
                                        i->first.get<NamedDecl *>());
      if (Instantiation->is<DeclArgumentPack *>()) {
        // We could expand this function parameter pack.
        NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
      } else {
        // We can't expand this function parameter pack, so we can't expand
        // the pack expansion.
        ShouldExpand = false;
        continue;
      }
    } else {
      // If we don't have a template argument at this depth/index, then we
      // cannot expand the pack expansion. Make a note of this, but we still
      // want to check any parameter packs we *do* have arguments for.
      if (Depth >= TemplateArgs.getNumLevels() ||
          !TemplateArgs.hasTemplateArgument(Depth, Index)) {
        ShouldExpand = false;
        continue;
      }

      // Determine the size of the argument pack.
      NewPackSize = TemplateArgs(Depth, Index).pack_size();
    }

    // C++0x [temp.arg.explicit]p9:
    //   Template argument deduction can extend the sequence of template
    //   arguments corresponding to a template parameter pack, even when the
    //   sequence contains explicitly specified template arguments.
    if (!IsFunctionParameterPack) {
      if (NamedDecl *PartialPack
                    = CurrentInstantiationScope->getPartiallySubstitutedPack()){
        unsigned PartialDepth, PartialIndex;
        std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
        if (PartialDepth == Depth && PartialIndex == Index)
          RetainExpansion = true;
      }
    }

    if (!NumExpansions) {
      // The is the first pack we've seen for which we have an argument.
      // Record it.
      NumExpansions = NewPackSize;
      FirstPack.first = Name;
      FirstPack.second = i->second;
      HaveFirstPack = true;
      continue;
    }

    if (NewPackSize != *NumExpansions) {
      // C++0x [temp.variadic]p5:
      //   All of the parameter packs expanded by a pack expansion shall have
      //   the same number of arguments specified.
      if (HaveFirstPack)
        Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
          << FirstPack.first << Name << *NumExpansions << NewPackSize
          << SourceRange(FirstPack.second) << SourceRange(i->second);
      else
        Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
          << Name << *NumExpansions << NewPackSize
          << SourceRange(i->second);
      return true;
    }
  }

  return false;
}
StringRef CodeCompletionTUInfo::getParentName(DeclContext *DC) {
  NamedDecl *ND = dyn_cast<NamedDecl>(DC);
  if (!ND)
    return StringRef();
  
  // Check whether we've already cached the parent name.
  StringRef &CachedParentName = ParentNames[DC];
  if (!CachedParentName.empty())
    return CachedParentName;

  // If we already processed this DeclContext and assigned empty to it, the
  // data pointer will be non-null.
  if (CachedParentName.data() != 0)
    return StringRef();

  // Find the interesting names.
  llvm::SmallVector<DeclContext *, 2> Contexts;
  while (DC && !DC->isFunctionOrMethod()) {
    if (NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
      if (ND->getIdentifier())
        Contexts.push_back(DC);
    }
    
    DC = DC->getParent();
  }

  {
    llvm::SmallString<128> S;
    llvm::raw_svector_ostream OS(S);
    bool First = true;
    for (unsigned I = Contexts.size(); I != 0; --I) {
      if (First)
        First = false;
      else {
        OS << "::";
      }
      
      DeclContext *CurDC = Contexts[I-1];
      if (ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
        CurDC = CatImpl->getCategoryDecl();
      
      if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
        ObjCInterfaceDecl *Interface = Cat->getClassInterface();
        if (!Interface) {
          // Assign an empty StringRef but with non-null data to distinguish
          // between empty because we didn't process the DeclContext yet.
          CachedParentName = StringRef((const char *)~0U, 0);
          return StringRef();
        }
        
        OS << Interface->getName() << '(' << Cat->getName() << ')';
      } else {
        OS << cast<NamedDecl>(CurDC)->getName();
      }
    }
    
    CachedParentName = AllocatorRef->CopyString(OS.str());
  }

  return CachedParentName;
}
Beispiel #4
0
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
                                ArrayRef<Token> AsmToks,SourceLocation EndLoc) {
  SmallVector<IdentifierInfo*, 4> Names;
  SmallVector<StringRef, 4> ConstraintRefs;
  SmallVector<Expr*, 4> Exprs;
  SmallVector<StringRef, 4> ClobberRefs;

  llvm::Triple TheTriple = Context.getTargetInfo().getTriple();
  llvm::Triple::ArchType ArchTy = TheTriple.getArch();
  bool UnsupportedArch = ArchTy != llvm::Triple::x86 &&
    ArchTy != llvm::Triple::x86_64;
  if (UnsupportedArch)
    Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
    
  // Empty asm statements don't need to instantiate the AsmParser, etc.
  if (UnsupportedArch || AsmToks.empty()) {
    StringRef EmptyAsmStr;
    MSAsmStmt *NS =
      new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
                              /*IsVolatile*/ true, AsmToks, /*NumOutputs*/ 0,
                              /*NumInputs*/ 0, Names, ConstraintRefs, Exprs,
                              EmptyAsmStr, ClobberRefs, EndLoc);
    return Owned(NS);
  }

  std::string AsmString;
  SmallVector<unsigned, 8> TokOffsets;
  if (buildMSAsmString(*this, AsmLoc, AsmToks, TokOffsets, AsmString))
    return StmtError();

  // Get the target specific parser.
  std::string Error;
  const std::string &TT = TheTriple.getTriple();
  const llvm::Target *TheTarget(llvm::TargetRegistry::lookupTarget(TT, Error));

  OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TT));
  OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
  OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
  OwningPtr<llvm::MCSubtargetInfo>
    STI(TheTarget->createMCSubtargetInfo(TT, "", ""));

  llvm::SourceMgr SrcMgr;
  llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
  llvm::MemoryBuffer *Buffer =
    llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());

  OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
  OwningPtr<llvm::MCAsmParser>
    Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
  OwningPtr<llvm::MCTargetAsmParser>
    TargetParser(TheTarget->createMCAsmParser(*STI, *Parser));

  // Get the instruction descriptor.
  const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); 
  llvm::MCInstPrinter *IP =
    TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);

  // Change to the Intel dialect.
  Parser->setAssemblerDialect(1);
  Parser->setTargetParser(*TargetParser.get());
  Parser->setParsingInlineAsm(true);
  TargetParser->setParsingInlineAsm(true);

  MCAsmParserSemaCallbackImpl MCAPSI(*this, AsmLoc, AsmToks, TokOffsets);
  TargetParser->setSemaCallback(&MCAPSI);
  SrcMgr.setDiagHandler(MCAsmParserSemaCallbackImpl::MSAsmDiagHandlerCallback,
                        &MCAPSI);

  unsigned NumOutputs;
  unsigned NumInputs;
  std::string AsmStringIR;
  SmallVector<std::pair<void *, bool>, 4> OpDecls;
  SmallVector<std::string, 4> Constraints;
  SmallVector<std::string, 4> Clobbers;
  if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR,
                               NumOutputs, NumInputs, OpDecls, Constraints,
                               Clobbers, MII, IP, MCAPSI))
    return StmtError();

  // Build the vector of clobber StringRefs.
  unsigned NumClobbers = Clobbers.size();
  ClobberRefs.resize(NumClobbers);
  for (unsigned i = 0; i != NumClobbers; ++i)
    ClobberRefs[i] = StringRef(Clobbers[i]);

  // Recast the void pointers and build the vector of constraint StringRefs.
  unsigned NumExprs = NumOutputs + NumInputs;
  Names.resize(NumExprs);
  ConstraintRefs.resize(NumExprs);
  Exprs.resize(NumExprs);
  for (unsigned i = 0, e = NumExprs; i != e; ++i) {
    NamedDecl *OpDecl = static_cast<NamedDecl *>(OpDecls[i].first);
    if (!OpDecl)
      return StmtError();

    DeclarationNameInfo NameInfo(OpDecl->getDeclName(), AsmLoc);
    ExprResult OpExpr = BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo,
                                                 OpDecl);
    if (OpExpr.isInvalid())
      return StmtError();

    // Need address of variable.
    if (OpDecls[i].second)
      OpExpr = BuildUnaryOp(getCurScope(), AsmLoc, clang::UO_AddrOf,
                            OpExpr.take());

    Names[i] = OpDecl->getIdentifier();
    ConstraintRefs[i] = StringRef(Constraints[i]);
    Exprs[i] = OpExpr.take();
  }

  bool IsSimple = NumExprs > 0;
  MSAsmStmt *NS =
    new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
                            /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
                            Names, ConstraintRefs, Exprs, AsmStringIR,
                            ClobberRefs, EndLoc);
  return Owned(NS);
}
Beispiel #5
0
void CodeCompletionBuilder::addParentContext(DeclContext *DC) {
    if (DC->isTranslationUnit()) {
        ParentKind = CXCursor_TranslationUnit;
        return;
    }

    if (DC->isFunctionOrMethod())
        return;

    NamedDecl *ND = dyn_cast<NamedDecl>(DC);
    if (!ND)
        return;

    ParentKind = getCursorKindForDecl(ND);

    // Check whether we've already cached the parent name.
    StringRef &CachedParentName = Allocator.getParentNames()[DC];
    if (!CachedParentName.empty()) {
        ParentName = CachedParentName;
        return;
    }

    // Find the interesting names.
    llvm::SmallVector<DeclContext *, 2> Contexts;
    while (DC && !DC->isFunctionOrMethod()) {
        if (NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
            if (ND->getIdentifier())
                Contexts.push_back(DC);
        }

        DC = DC->getParent();
    }

    {
        llvm::SmallString<128> S;
        llvm::raw_svector_ostream OS(S);
        bool First = true;
        for (unsigned I = Contexts.size(); I != 0; --I) {
            if (First)
                First = false;
            else {
                OS << "::";
            }

            DeclContext *CurDC = Contexts[I-1];
            if (ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
                CurDC = CatImpl->getCategoryDecl();

            if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
                ObjCInterfaceDecl *Interface = Cat->getClassInterface();
                if (!Interface)
                    return;

                OS << Interface->getName() << '(' << Cat->getName() << ')';
            } else {
                OS << cast<NamedDecl>(CurDC)->getName();
            }
        }

        ParentName = Allocator.CopyString(OS.str());
        CachedParentName = ParentName;
    }
}