bool RSExportReduce::analyzeTranslationUnit() { RSContext &RSC = *getRSContext(); clang::Preprocessor &PP = RSC.getPreprocessor(); StateOfAnalyzeTranslationUnit S( RSC, PP, RSC.getASTContext(), [&PP, this] (const char *Key, const std::string &Name) { std::ostringstream Description; Description << Key << " " << Name << "()" << " for '#pragma rs " << KeyReduce << "(" << mNameReduce << ")'" << " (" << mLocation.printToString(PP.getSourceManager()) << ")"; return Description.str(); }); S.FnInitializer = lookupFunction(S, KeyInitializer, mNameInitializer); S.FnAccumulator = lookupFunction(S, KeyAccumulator, mNameAccumulator); S.FnCombiner = lookupFunction(S, KeyCombiner, mNameCombiner); S.FnOutConverter = lookupFunction(S, KeyOutConverter, mNameOutConverter); S.FnHalter = lookupFunction(S, KeyHalter, mNameHalter); if (!S.Ok) return false; analyzeInitializer(S); analyzeAccumulator(S); analyzeCombiner(S); analyzeOutConverter(S); analyzeHalter(S); analyzeResultType(S); return S.Ok; }
bool RSExportFunc::checkParameterPacketType(llvm::StructType *ParamTy) const { if (ParamTy == NULL) return !hasParam(); else if (!hasParam()) return false; slangAssert(mParamPacketType != NULL); const RSExportRecordType *ERT = mParamPacketType; // must have same number of elements if (ERT->getFields().size() != ParamTy->getNumElements()) return false; const llvm::StructLayout *ParamTySL = getRSContext()->getTargetData()->getStructLayout(ParamTy); unsigned Index = 0; for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), FE = ERT->fields_end(); FI != FE; FI++, Index++) { const RSExportRecordType::Field *F = *FI; llvm::Type *T1 = F->getType()->getLLVMType(); llvm::Type *T2 = ParamTy->getTypeAtIndex(Index); // Fast check if (T1 == T2) continue; // Check offset size_t T1Offset = F->getOffsetInParent(); size_t T2Offset = ParamTySL->getElementOffset(Index); if (T1Offset != T2Offset) return false; // Check size size_t T1Size = RSExportType::GetTypeAllocSize(F->getType()); size_t T2Size = getRSContext()->getTargetData()->getTypeAllocSize(T2); if (T1Size != T2Size) return false; } return true; }
// does update S.Ok clang::FunctionDecl *RSExportReduce::lookupFunction(StateOfAnalyzeTranslationUnit &S, const char *Kind, const llvm::StringRef &Name) { if (Name.empty()) return nullptr; clang::TranslationUnitDecl *TUDecl = getRSContext()->getASTContext().getTranslationUnitDecl(); slangAssert(TUDecl); clang::FunctionDecl *Ret = nullptr; const clang::IdentifierInfo *II = S.PP.getIdentifierInfo(Name); if (II) { for (auto Decl : TUDecl->lookup(II)) { clang::FunctionDecl *FDecl = Decl->getAsFunction(); if (!FDecl || !FDecl->isThisDeclarationADefinition()) continue; if (Ret) { S.RSC.ReportError(mLocation, "duplicate function definition for '%0(%1)' for '#pragma rs %2(%3)' (%4, %5)") << Kind << Name << KeyReduce << mNameReduce << Ret->getLocation().printToString(S.PP.getSourceManager()) << FDecl->getLocation().printToString(S.PP.getSourceManager()); S.Ok = false; return nullptr; } Ret = FDecl; } } if (!Ret) { // Either the identifier lookup failed, or we never found the function definition. S.RSC.ReportError(mLocation, "could not find function definition for '%0(%1)' for '#pragma rs %2(%3)'") << Kind << Name << KeyReduce << mNameReduce; S.Ok = false; return nullptr; } if (Ret) { // Must have internal linkage if (Ret->getFormalLinkage() != clang::InternalLinkage) { S.RSC.ReportError(Ret->getLocation(), "%0 must be static") << S.DiagnosticDescription(Kind, Name); S.Ok = false; } } if (Ret == nullptr) S.Ok = false; return Ret; }