void IdentifierResolver::iterator::incrementSlowCase() { NamedDecl *D = **this; //@@ assert(!D->getDeclName().getAsIdentifierInfo() || !D->getDeclName().getAsIdentifierInfo()->isMetaGenerated()); //@@ void *InfoPtr = D->getDeclName().getFETokenInfo<void>(); assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?"); IdDeclInfo *Info = toIdDeclInfo(InfoPtr); BaseIter I = getIterator(); if (I != Info->decls_begin()) *this = iterator(I-1); else // No more decls. *this = iterator(); }
void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); assert((D->NextInContextAndBits.getPointer() || D == LastDecl) && "decl is not in decls list"); // Remove D from the decl chain. This is O(n) but hopefully rare. if (D == FirstDecl) { if (D == LastDecl) FirstDecl = LastDecl = 0; else FirstDecl = D->NextInContextAndBits.getPointer(); } else { for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) { assert(I && "decl not found in linked list"); if (I->NextInContextAndBits.getPointer() == D) { I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer()); if (D == LastDecl) LastDecl = I; break; } } } // Mark that D is no longer in the decl chain. D->NextInContextAndBits.setPointer(0); // Remove D from the lookup table if necessary. if (isa<NamedDecl>(D)) { NamedDecl *ND = cast<NamedDecl>(D); // Remove only decls that have a name or registered in the lookup. if (!ND->getDeclName() || ND->isHidden()) return; StoredDeclsMap *Map = D->getDeclContext()->getPrimaryContext()->LookupPtr.getPointer(); if (!Map) return; StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); #ifndef NDEBUG assert(Pos != Map->end() && "no lookup entry for decl"); #endif if (Pos != Map->end() && (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND) ) Pos->second.remove(ND); } }
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity) { const CXXRecordDecl *NamingClass = Entity.getNamingClass(); const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass(); NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0); S.Diag(Loc, Entity.getDiag()) << (Entity.getAccess() == AS_protected) << (D ? D->getDeclName() : DeclarationName()) << S.Context.getTypeDeclType(NamingClass) << S.Context.getTypeDeclType(DeclaringClass); DiagnoseAccessPath(S, EC, Entity); }
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; }
///\brief Checks for clashing names when trying to extract a declaration. /// ///\returns true if there is another declaration with the same name bool DeclExtractor::CheckForClashingNames( const llvm::SmallVector<NamedDecl*, 4>& Decls, DeclContext* DC, Scope* S) { for (size_t i = 0; i < Decls.size(); ++i) { NamedDecl* ND = Decls[i]; if (TagDecl* TD = dyn_cast<TagDecl>(ND)) { LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(), Sema::LookupTagName, Sema::ForRedeclaration ); m_Sema->LookupName(Previous, S); // There is no function diagnosing the redeclaration of tags (eg. enums). // So either we have to do it by hand or we can call the top-most // function that does the check. Currently the top-most clang function // doing the checks creates an AST node, which we don't want. if (!CheckTagDeclaration(TD, Previous)) return true; } else if (VarDecl* VD = dyn_cast<VarDecl>(ND)) { LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration ); m_Sema->LookupName(Previous, S); m_Sema->CheckVariableDeclaration(VD, Previous); if (VD->isInvalidDecl()) return true; // This var decl will likely get referenced later; claim that it's used. VD->setIsUsed(); } } return false; }
void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); assert((D->NextDeclInContext || D == LastDecl) && "decl is not in decls list"); // Remove D from the decl chain. This is O(n) but hopefully rare. if (D == FirstDecl) { if (D == LastDecl) FirstDecl = LastDecl = 0; else FirstDecl = D->NextDeclInContext; } else { for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) { assert(I && "decl not found in linked list"); if (I->NextDeclInContext == D) { I->NextDeclInContext = D->NextDeclInContext; if (D == LastDecl) LastDecl = I; break; } } } // Mark that D is no longer in the decl chain. D->NextDeclInContext = 0; // Remove D from the lookup table if necessary. if (isa<NamedDecl>(D)) { NamedDecl *ND = cast<NamedDecl>(D); StoredDeclsMap *Map = getPrimaryContext()->LookupPtr; if (!Map) return; StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); assert(Pos != Map->end() && "no lookup entry for decl"); Pos->second.remove(ND); } }
void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out) const { switch (getKind()) { case Null: Out << "<no value>"; break; case Type: { PrintingPolicy SubPolicy(Policy); SubPolicy.SuppressStrongLifetime = true; getAsType().print(Out, SubPolicy); break; } case Declaration: { NamedDecl *ND = cast<NamedDecl>(getAsDecl()); Out << '&'; if (ND->getDeclName()) { // FIXME: distinguish between pointer and reference args? ND->printQualifiedName(Out); } else { Out << "<anonymous>"; } break; } case NullPtr: Out << "nullptr"; break; case Template: getAsTemplate().print(Out, Policy); break; case TemplateExpansion: getAsTemplateOrTemplatePattern().print(Out, Policy); Out << "..."; break; case Integral: { printIntegral(*this, Out); break; } case Expression: getAsExpr()->printPretty(Out, 0, Policy); break; case Pack: Out << "<"; bool First = true; for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { if (First) First = false; else Out << ", "; P->print(Policy, Out); } Out << ">"; break; } }
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); }
// Adapted from tools\clang\lib\AST\TemplateBase.cpp TemplateArgument::print void printTemplateArgument(raw_ostream &out, const PrintingPolicy &policy, TemplateArgument const &arg, bool qualifyNames) { switch (arg.getKind()) { case TemplateArgument::Null: out << "(no value)"; break; case TemplateArgument::Type: { PrintingPolicy SubPolicy(policy); SubPolicy.SuppressStrongLifetime = true; arg.getAsType().print(out, SubPolicy); break; } case TemplateArgument::Declaration: { NamedDecl *ND = cast<NamedDecl>(arg.getAsDecl()); out << '&'; if (ND->getDeclName()) { // FIXME: distinguish between pointer and reference args? ND->printQualifiedName(out); } else { out << "(anonymous)"; } break; } case TemplateArgument::NullPtr: out << "nullptr"; break; case TemplateArgument::Template: // Orig: arg.getAsTemplate().print(out, policy); { auto templateName = arg.getAsTemplate(); printTemplateName(out, policy, templateName, qualifyNames); break; } case TemplateArgument::TemplateExpansion: arg.getAsTemplateOrTemplatePattern().print(out, policy); out << "..."; break; case TemplateArgument::Integral: { printIntegral(arg, out, policy); break; } case TemplateArgument::Expression: arg.getAsExpr()->printPretty(out, nullptr, policy); break; case TemplateArgument::Pack: out << "<"; bool First = true; for (const auto &P : arg.pack_elements()) { if (First) First = false; else out << ", "; P.print(policy, out); } out << ">"; break; } }