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; }
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); }
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; } }