// DependentScopeDeclRefExpr DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, true, true, (NameInfo.isInstantiationDependent() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()))), QualifierLoc(QualifierLoc), NameInfo(NameInfo), HasExplicitTemplateArgs(Args != 0) { if (Args) { bool Dependent = true; bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = ExprBits.ContainsUnexpandedParameterPack; reinterpret_cast<ASTTemplateArgumentListInfo*>(this+1) ->initializeFrom(*Args, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; } }
bool RVASTVisitor::rewriteFuncDecl(FunctionDecl *FD) { DeclarationNameInfo NameInfo = FD->getNameInfo(); SourceLocation NameInfoStartLoc = NameInfo.getBeginLoc(); SourceRange FuncDefRange = FD->getSourceRange(); SourceLocation FuncStartLoc = FuncDefRange.getBegin(); const char *FuncStartBuf = ConsumerInstance->SrcManager->getCharacterData(FuncStartLoc); const char *NameInfoStartBuf = ConsumerInstance->SrcManager->getCharacterData(NameInfoStartLoc); if (FuncStartBuf == NameInfoStartBuf) return true; int Offset = NameInfoStartBuf - FuncStartBuf; NameInfoStartBuf--; while ((*NameInfoStartBuf == '(') || (*NameInfoStartBuf == ' ') || (*NameInfoStartBuf == '\t') || (*NameInfoStartBuf == '\n')) { Offset--; NameInfoStartBuf--; } TransAssert(Offset >= 0); ConsumerInstance->Rewritten = true; return !(ConsumerInstance->TheRewriter.ReplaceText(FuncStartLoc, Offset, "void ")); }
ExprResult Sema::LookupInlineAsmVarDeclField(Expr *E, StringRef Member, llvm::InlineAsmIdentifierInfo &Info, SourceLocation AsmLoc) { Info.clear(); QualType T = E->getType(); if (T->isDependentType()) { DeclarationNameInfo NameInfo; NameInfo.setLoc(AsmLoc); NameInfo.setName(&Context.Idents.get(Member)); return CXXDependentScopeMemberExpr::Create( Context, E, T, /*IsArrow=*/false, AsmLoc, NestedNameSpecifierLoc(), SourceLocation(), /*FirstQualifierInScope=*/nullptr, NameInfo, /*TemplateArgs=*/nullptr); } const RecordType *RT = T->getAs<RecordType>(); // FIXME: Diagnose this as field access into a scalar type. if (!RT) return ExprResult(); LookupResult FieldResult(*this, &Context.Idents.get(Member), AsmLoc, LookupMemberName); if (!LookupQualifiedName(FieldResult, RT->getDecl())) return ExprResult(); // Only normal and indirect field results will work. ValueDecl *FD = dyn_cast<FieldDecl>(FieldResult.getFoundDecl()); if (!FD) FD = dyn_cast<IndirectFieldDecl>(FieldResult.getFoundDecl()); if (!FD) return ExprResult(); // Make an Expr to thread through OpDecl. ExprResult Result = BuildMemberReferenceExpr( E, E->getType(), AsmLoc, /*IsArrow=*/false, CXXScopeSpec(), SourceLocation(), nullptr, FieldResult, nullptr, nullptr); if (Result.isInvalid()) return Result; Info.OpDecl = Result.get(); fillInlineAsmTypeInfo(Context, Result.get()->getType(), Info); // Fields are "variables" as far as inline assembly is concerned. Info.IsVarDecl = true; return Result; }
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()) || MemberNameInfo.containsUnexpandedParameterPack())), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(TemplateArgs != 0), OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), FirstQualifierFoundInScope(FirstQualifierFoundInScope), MemberNameInfo(MemberNameInfo) { if (TemplateArgs) { bool Dependent = true; bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } }
int runFD(const FunctionDecl *md, SourceManager &sm) { if (!md->hasBody()) return 0; if (!md->isThisDeclarationADefinition()) return 0; DeclarationNameInfo info = md->getNameInfo(); FullSourceLoc b(md->getLocStart(), sm), _e(md->getLocEnd(), sm); FullSourceLoc e(clang::Lexer::getLocForEndOfToken(_e, 0, sm, *this->lopt), sm); SourceRange nameRange = SourceRange(info.getLoc()); FullSourceLoc d(nameRange.getBegin(), sm), _f(nameRange.getEnd(), sm); FullSourceLoc f(clang::Lexer::getLocForEndOfToken(_f, 0, sm, *this->lopt), sm); string start(sm.getCharacterData(b), sm.getCharacterData(d)-sm.getCharacterData(b)); string name(sm.getCharacterData(d), sm.getCharacterData(f)-sm.getCharacterData(d)); string end(sm.getCharacterData(f), sm.getCharacterData(e)-sm.getCharacterData(f)); if (this->methods.find(name) != this->methods.end()) { message("Redefinition of method " + name); return 1; } METHOD* m = new METHOD(); m->pre = start; m->name = name; m->post = end; getAbsoluteLocation(FullSourceLoc(md->getLocStart(), sm), FullSourceLoc(md->getLocEnd(), sm), &m->location.begin, &m->location.end, *this->lopt); m->sm = &sm; m->range = CharSourceRange:: getTokenRange(SourceRange(info.getLoc())); this->methods[name] = m; // For debugging purposes // cout << start << "|" << name << "|" << end << endl; return 0; }
bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, UnexpandedParameterPackContext UPPC) { // C++0x [temp.variadic]p5: // An appearance of a name of a parameter pack that is not expanded is // ill-formed. switch (NameInfo.getName().getNameKind()) { case DeclarationName::Identifier: case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: case DeclarationName::CXXOperatorName: case DeclarationName::CXXLiteralOperatorName: case DeclarationName::CXXUsingDirective: return false; case DeclarationName::CXXConstructorName: case DeclarationName::CXXDestructorName: case DeclarationName::CXXConversionFunctionName: // FIXME: We shouldn't need this null check! if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC); if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack()) return false; break; } SmallVector<UnexpandedParameterPack, 2> Unexpanded; CollectUnexpandedParameterPacksVisitor(Unexpanded) .TraverseType(NameInfo.getName().getCXXNameType()); assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded); }
int runCE(const CallExpr *md, SourceManager &sm) { const FunctionDecl* dcallee = md->getDirectCallee(); // Only care about callees that can be determined at // compile time (no black magic with function pointers) if (dcallee == 0) return 0; DeclarationNameInfo info = dcallee->getNameInfo(); std::string name = info.getAsString(); // Maybe it's calling external code, if it has no // local body then the call is irrelevant auto method = this->methods.find(name); if (method == this->methods.end()) return 0; const Decl* callee = md->getCalleeDecl(); CALLSITE* s = new CALLSITE(); getAbsoluteLocation(FullSourceLoc(md->getLocStart(), sm), FullSourceLoc(md->getLocEnd(), sm), &s->location.begin, &s->location.end, *this->lopt); s->sm = &sm; s->range = CharSourceRange:: getTokenRange(SourceRange(callee->getLocation())); method->second->calls.push_back(s); // For debugging purposes // cout << name << endl; return 0; }
bool RewriteUtils::replaceCXXDestructorDeclName( const CXXDestructorDecl *DtorDecl, const std::string &Name) { SourceLocation StartLoc = DtorDecl->getLocation(); const char *StartBuf = SrcManager->getCharacterData(StartLoc); TransAssert((*StartBuf == '~') && "Invalid Destructor Location"); // FIXME: it's quite ugly, better to use clang's Lexer unsigned Off = 0; StartBuf++; while (isspace(*StartBuf)) { StartBuf++; Off++; } std::string DName = DtorDecl->getNameAsString(); DeclarationNameInfo NameInfo = DtorDecl->getNameInfo(); DeclarationName DeclName = NameInfo.getName(); const Type *Ty = DeclName.getCXXNameType().getTypePtr(); size_t NameLen; if (Ty->getTypeClass() == Type::InjectedClassName) { const CXXRecordDecl *CXXRD = Ty->getAsCXXRecordDecl(); std::string RDName = CXXRD->getNameAsString(); NameLen = DName.find(RDName); TransAssert((NameLen != std::string::npos) && "Cannot find RecordDecl Name!"); NameLen += RDName.length(); } else { NameLen = DName.length(); } NameLen += Off; return !TheRewriter->ReplaceText(StartLoc, NameLen, "~" + Name); }
// I didn't factor out the common part of this function // into RewriteUtils, because the common part has implicit // dependency on VisitTemplateSpecializationTypeLoc. If in another // transformation we use this utility without implementing // VisitTemplateSpecializationTypeLoc, we will be in trouble. bool RemoveNamespaceRewriteVisitor::VisitCXXDestructorDecl( CXXDestructorDecl *DtorDecl) { if (ConsumerInstance->isForUsingNamedDecls) return true; const DeclContext *Ctx = DtorDecl->getDeclContext(); const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(Ctx); TransAssert(CXXRD && "Invalid CXXRecordDecl"); std::string Name; if (!ConsumerInstance->getNewNamedDeclName(CXXRD, Name)) return true; // Avoid duplicated VisitDtor. // For example, in the code below: // template<typename T> // class SomeClass { // public: // ~SomeClass<T>() {} // }; // ~SomeClass<T>'s TypeLoc is represented as TemplateSpecializationTypeLoc // In this case, ~SomeClass will be renamed from // VisitTemplateSpecializationTypeLoc. DeclarationNameInfo NameInfo = DtorDecl->getNameInfo(); if ( TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) { TypeLoc DtorLoc = TSInfo->getTypeLoc(); if (!DtorLoc.isNull() && (DtorLoc.getTypeLocClass() == TypeLoc::TemplateSpecialization)) return true; } ConsumerInstance->RewriteHelper->replaceCXXDestructorDeclName(DtorDecl, Name); return true; }
bool RewriteUtils::replaceFunctionDeclName(const FunctionDecl *FD, const std::string &NameStr) { // We cannot naively use FD->getNameAsString() here. // For example, for a template class // template<typename T> // class SomeClass { // public: // SomeClass() {} // }; // applying getNameAsString() on SomeClass() gives us SomeClass<T>. DeclarationNameInfo NameInfo = FD->getNameInfo(); DeclarationName DeclName = NameInfo.getName(); DeclarationName::NameKind K = DeclName.getNameKind(); TransAssert((K != DeclarationName::CXXDestructorName) && "Cannot rename CXXDestructorName here!"); std::string FDName = FD->getNameAsString(); size_t FDNameLen = FD->getNameAsString().length(); if (K == DeclarationName::CXXConstructorName) { const Type *Ty = DeclName.getCXXNameType().getTypePtr(); if (Ty->getTypeClass() == Type::InjectedClassName) { const CXXRecordDecl *CXXRD = Ty->getAsCXXRecordDecl(); std::string RDName = CXXRD->getNameAsString(); FDNameLen = FDName.find(RDName); TransAssert((FDNameLen != std::string::npos) && "Cannot find RecordDecl Name!"); FDNameLen += RDName.length(); } } return !TheRewriter->ReplaceText(NameInfo.getLoc(), FDNameLen, NameStr); }
CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()-> containsUnexpandedParameterPack()) || MemberNameInfo.containsUnexpandedParameterPack())), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(false), OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), FirstQualifierFoundInScope(FirstQualifierFoundInScope), MemberNameInfo(MemberNameInfo) { }
ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id) { LookupResult Lookup(*this, Id, LookupOrdinaryName); LookupParsedName(Lookup, CurScope, &ScopeSpec, true); if (Lookup.isAmbiguous()) return ExprError(); VarDecl *VD; if (!Lookup.isSingleResult()) { VarDeclFilterCCC Validator(*this); if (TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope, 0, Validator)) { diagnoseTypo(Corrected, PDiag(Lookup.empty()? diag::err_undeclared_var_use_suggest : diag::err_omp_expected_var_arg_suggest) << Id.getName()); VD = Corrected.getCorrectionDeclAs<VarDecl>(); } else { Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use : diag::err_omp_expected_var_arg) << Id.getName(); return ExprError(); } } else { if (!(VD = Lookup.getAsSingle<VarDecl>())) { Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); return ExprError(); } } Lookup.suppressDiagnostics(); // OpenMP [2.9.2, Syntax, C/C++] // Variables must be file-scope, namespace-scope, or static block-scope. if (!VD->hasGlobalStorage()) { Diag(Id.getLoc(), diag::err_omp_global_var_arg) << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD; return ExprError(); } VarDecl *CanonicalVD = VD->getCanonicalDecl(); NamedDecl *ND = cast<NamedDecl>(CanonicalVD); // OpenMP [2.9.2, Restrictions, C/C++, p.2] // A threadprivate directive for file-scope variables must appear outside // any definition or declaration. if (CanonicalVD->getDeclContext()->isTranslationUnit() && !getCurLexicalContext()->isTranslationUnit()) { Diag(Id.getLoc(), diag::err_omp_var_scope) << getOpenMPDirectiveName(OMPD_threadprivate) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD; return ExprError(); } // OpenMP [2.9.2, Restrictions, C/C++, p.3] // A threadprivate directive for static class member variables must appear // in the class definition, in the same scope in which the member // variables are declared. if (CanonicalVD->isStaticDataMember() && !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { Diag(Id.getLoc(), diag::err_omp_var_scope) << getOpenMPDirectiveName(OMPD_threadprivate) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD; return ExprError(); } // OpenMP [2.9.2, Restrictions, C/C++, p.4] // A threadprivate directive for namespace-scope variables must appear // outside any definition or declaration other than the namespace // definition itself. if (CanonicalVD->getDeclContext()->isNamespace() && (!getCurLexicalContext()->isFileContext() || !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { Diag(Id.getLoc(), diag::err_omp_var_scope) << getOpenMPDirectiveName(OMPD_threadprivate) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD; return ExprError(); } // OpenMP [2.9.2, Restrictions, C/C++, p.6] // A threadprivate directive for static block-scope variables must appear // in the scope of the variable and not in a nested scope. if (CanonicalVD->isStaticLocal() && CurScope && !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { Diag(Id.getLoc(), diag::err_omp_var_scope) << getOpenMPDirectiveName(OMPD_threadprivate) << VD; bool IsDecl = VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD; return ExprError(); } // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] // A threadprivate directive must lexically precede all references to any // of the variables in its list. if (VD->isUsed()) { Diag(Id.getLoc(), diag::err_omp_var_used) << getOpenMPDirectiveName(OMPD_threadprivate) << VD; return ExprError(); } QualType ExprType = VD->getType().getNonReferenceType(); ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_RValue, Id.getLoc()); DSAStack->addDSA(VD, cast<DeclRefExpr>(DE.get()), OMPC_threadprivate); return DE; }
OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent, bool KnownContainsUnexpandedParameterPack) : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, KnownDependent, (KnownInstantiationDependent || NameInfo.isInstantiationDependent() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (KnownContainsUnexpandedParameterPack || NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() ->containsUnexpandedParameterPack()))), Results(0), NumResults(End - Begin), NameInfo(NameInfo), QualifierLoc(QualifierLoc), HasExplicitTemplateArgs(TemplateArgs != 0) { NumResults = End - Begin; if (NumResults) { // Determine whether this expression is type-dependent. for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) { if ((*I)->getDeclContext()->isDependentContext() || isa<UnresolvedUsingValueDecl>(*I)) { ExprBits.TypeDependent = true; ExprBits.ValueDependent = true; } } Results = static_cast<DeclAccessPair *>( C.Allocate(sizeof(DeclAccessPair) * NumResults, llvm::alignOf<DeclAccessPair>())); memcpy(Results, &*Begin.getIterator(), NumResults * sizeof(DeclAccessPair)); } // If we have explicit template arguments, check for dependent // template arguments and whether they contain any unexpanded pack // expansions. if (TemplateArgs) { bool Dependent = false; bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); if (Dependent) { ExprBits.TypeDependent = true; ExprBits.ValueDependent = true; } if (InstantiationDependent) ExprBits.InstantiationDependent = true; if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } if (isTypeDependent()) setType(C.DependentTy); }