int test_headBlocked(void) { int success = 1; semd_t *s1, *s2; pcb_t *p1, *p2, *p3; initASL(); initProc(); s1 = getSema(0); initSemD(&s1, 1); s2 = getSema(1); initSemD(&s2, 2); p1 = allocPcb(); p2 = allocPcb(); p3 = allocPcb(); success &= headBlocked(NULL) == NULL; success &= headBlocked(s1) == NULL; success &= headBlocked(s2) == NULL; insertBlocked(s1, p1); insertBlocked(s2, p2); insertBlocked(s1, p3); success &= headBlocked(s1) == p1; success &= headBlocked(s2) == p2; outBlocked(p1); success &= headBlocked(s1) == p3; return success; }
int test_removeBlocked(void) { int success = 1; semd_t *s1, *s2; pcb_t *p1, *p2, *p3; initASL(); initProc(); s1 = getSema(0); initSemD(&s1, 1); s2 = getSema(1); initSemD(&s2, 2); p1 = allocPcb(); p2 = allocPcb(); p3 = allocPcb(); insertBlocked(s1, p1); insertBlocked(s2, p2); insertBlocked(s1, p3); success &= removeBlocked(NULL) == NULL; success &= getSNext(s1) == s2; success &= removeBlocked(s2) == p2; success &= getSemdFree() == s2; success &= getSNext(s1) == NULL; success &= removeBlocked(s1) == p1; success &= removeBlocked(s1) == p3; success &= getSemdFree() == s1; success &= getASL() == NULL; return success; }
Interpreter::CompilationResult Interpreter::loadModuleForHeader(const std::string& headerFile) { Preprocessor& PP = getCI()->getPreprocessor(); //Copied from clang's PPDirectives.cpp bool isAngled = false; // Clang doc says: // "LookupFrom is set when this is a \#include_next directive, it specifies // the file to start searching from." const DirectoryLookup* LookupFrom = 0; const DirectoryLookup* CurDir = 0; ModuleMap::KnownHeader suggestedModule; // PP::LookupFile uses it to issue 'nice' diagnostic SourceLocation fileNameLoc; PP.LookupFile(fileNameLoc, headerFile, isAngled, LookupFrom, CurDir, /*SearchPath*/0, /*RelativePath*/ 0, &suggestedModule, /*SkipCache*/false, /*OpenFile*/ false, /*CacheFail*/ false); if (!suggestedModule) return Interpreter::kFailure; // Copied from PPDirectives.cpp SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> path; for (Module *mod = suggestedModule.getModule(); mod; mod = mod->Parent) { IdentifierInfo* II = &getSema().getPreprocessor().getIdentifierTable().get(mod->Name); path.push_back(std::make_pair(II, fileNameLoc)); } std::reverse(path.begin(), path.end()); // Pretend that the module came from an inclusion directive, so that clang // will create an implicit import declaration to capture it in the AST. bool isInclude = true; SourceLocation includeLoc; if (getCI()->loadModule(includeLoc, path, Module::AllVisible, isInclude)) { // After module load we need to "force" Sema to generate the code for // things like dynamic classes. getSema().ActOnEndOfTranslationUnit(); return Interpreter::kSuccess; } return Interpreter::kFailure; }
int test_insertBlocked(void) { int success = 1; semd_t *s1, *s2, *s3; pcb_t *p1, *p2, *p3; pcbq_t *q; initASL(); initProc(); s1 = getSema(0); initSemD(&s1, 1); s2 = getSema(1); initSemD(&s2, 2); s3 = getSema(12); initSemD(&s3, 3); p1 = allocPcb(); p2 = allocPcb(); p3 = allocPcb(); success &= getASL() == NULL; insertBlocked(NULL, p1); success &= getASL() == NULL; insertBlocked(s1, NULL); success &= getASL() == NULL; insertBlocked(s2, p2); q = getSProcQ(s2); success &= !emptyProcQ(q); success &= getASL() == s2; insertBlocked(s3, p3); q = getSProcQ(s3); success &= !emptyProcQ(q); success &= getASL() == s2; success &= getSNext(s2) == s3; insertBlocked(s1, p1); q = getSProcQ(s1); success &= !emptyProcQ(q); success &= getASL() == s1; success &= getSNext(s1) == s2; return success; }
int test_initASL(void) { int i; int success = 1; semd_t *s1, *s2; initASL(); for (i = 0; i < MAXPROCESS-1; ++i) { s1 = getSema(i); s2 = getSema(i+1); success &= getSNext(s1) == s2; } s1 = getSema(MAXPROCESS - 1); success &= getSNext(s1) == NULL; success &= getSemdFree() == getSema(0); return success; }
void Interpreter::setCallbacks(InterpreterCallbacks* C) { if (m_Callbacks.get() == C) return; // We need it to enable LookupObject callback. if (!m_Callbacks) m_Callbacks.reset(C); else m_Callbacks->setNext(C); // FIXME: We should add a multiplexer in the ASTContext, too. llvm::IntrusiveRefCntPtr<ExternalASTSource> astContextExternalSource(getSema().getExternalSource()); clang::ASTContext& Ctx = getSema().getASTContext(); // FIXME: This is a gross hack. We must make multiplexer in the astcontext, // or a derived class that extends what we need. Ctx.ExternalSource.resetWithoutRelease(); // FIXME: make sure we delete it. Ctx.setExternalSource(astContextExternalSource); if (DynamicLibraryManager* DLM = getDynamicLibraryManager()) DLM->setCallbacks(C); }
bool Interpreter::ShouldWrapInput(const std::string& input) { // TODO: For future reference. // Parser* P = const_cast<clang::Parser*>(m_IncrParser->getParser()); // Parser::TentativeParsingAction TA(P); // TPResult result = P->isCXXDeclarationSpecifier(); // TA.Revert(); // return result == TPResult::True(); // FIXME: can't skipToEndOfLine because we don't want to PragmaLex // because we don't want to pollute the preprocessor. Without PragmaLex // there is no "end of line" / eod token. So skip the #line before lexing. size_t posStart = 0; size_t lenInput = input.length(); while (lenInput > posStart && isspace(input[posStart])) ++posStart; // Don't wrap empty input if (posStart == lenInput) return false; if (input[posStart] == '#') { size_t posDirective = posStart + 1; while (lenInput > posDirective && isspace(input[posDirective])) ++posDirective; // A single '#'? Weird... better don't wrap. if (posDirective == lenInput) return false; if (!strncmp(&input[posDirective], "line ", 5)) { // There is a line directive. It does affect the determination whether // this input should be wrapped; skip the line. size_t posEOD = input.find('\n', posDirective + 5); if (posEOD != std::string::npos) posStart = posEOD + 1; } } //llvm::OwningPtr<llvm::MemoryBuffer> buf; //buf.reset(llvm::MemoryBuffer::getMemBuffer(&input[posStart], // "Cling Preparse Buf")); Lexer WrapLexer(SourceLocation(), getSema().getLangOpts(), input.c_str() + posStart, input.c_str() + posStart, input.c_str() + input.size()); Token Tok; WrapLexer.LexFromRawLexer(Tok); const tok::TokenKind kind = Tok.getKind(); if (kind == tok::raw_identifier && !Tok.needsCleaning()) { StringRef keyword(Tok.getRawIdentifier()); if (keyword.equals("using")) { // FIXME: Using definitions and declarations should be decl extracted. // Until we have that, don't wrap them if they are the only input. const char* cursor = keyword.data(); cursor = strchr(cursor, ';'); // advance to end of using decl / def. if (!cursor) { // Using decl / def without trailing ';' means input consists of only // that using decl /def: should not wrap. return false; } // Skip whitespace after ';' do ++cursor; while (*cursor && isspace(*cursor)); if (!*cursor) return false; // There is "more" - let's assume this input consists of a using // declaration or definition plus some code that should be wrapped. return true; } if (keyword.equals("extern")) return false; if (keyword.equals("namespace")) return false; if (keyword.equals("template")) return false; } else if (kind == tok::hash) { WrapLexer.LexFromRawLexer(Tok); if (Tok.is(tok::raw_identifier) && !Tok.needsCleaning()) { StringRef keyword(Tok.getRawIdentifier()); if (keyword.equals("include")) return false; } } return true; }
Interpreter::Interpreter(int argc, const char* const *argv, const char* llvmdir /*= 0*/, bool noRuntime) : m_UniqueCounter(0), m_PrintDebug(false), m_DynamicLookupEnabled(false), m_RawInputEnabled(false), m_LastCustomPragmaDiagPopPoint(){ m_LLVMContext.reset(new llvm::LLVMContext); std::vector<unsigned> LeftoverArgsIdx; m_Opts = InvocationOptions::CreateFromArgs(argc, argv, LeftoverArgsIdx); std::vector<const char*> LeftoverArgs; for (size_t I = 0, N = LeftoverArgsIdx.size(); I < N; ++I) { LeftoverArgs.push_back(argv[LeftoverArgsIdx[I]]); } m_DyLibManager.reset(new DynamicLibraryManager(getOptions())); m_IncrParser.reset(new IncrementalParser(this, LeftoverArgs.size(), &LeftoverArgs[0], llvmdir)); Sema& SemaRef = getSema(); Preprocessor& PP = SemaRef.getPreprocessor(); // Enable incremental processing, which prevents the preprocessor destroying // the lexer on EOF token. PP.enableIncrementalProcessing(); m_LookupHelper.reset(new LookupHelper(new Parser(PP, SemaRef, /*SkipFunctionBodies*/false, /*isTemp*/true), this)); if (!isInSyntaxOnlyMode()) { llvm::Module* theModule = m_IncrParser->getCodeGenerator()->GetModule(); m_Executor.reset(new IncrementalExecutor(theModule, SemaRef.Diags)); } // Tell the diagnostic client that we are entering file parsing mode. DiagnosticConsumer& DClient = getCI()->getDiagnosticClient(); DClient.BeginSourceFile(getCI()->getLangOpts(), &PP); llvm::SmallVector<Transaction*, 2> IncrParserTransactions; m_IncrParser->Initialize(IncrParserTransactions); handleFrontendOptions(); AddRuntimeIncludePaths(argv[0]); if (!noRuntime) { if (getCI()->getLangOpts().CPlusPlus) IncludeCXXRuntime(); else IncludeCRuntime(); } // Commit the transactions, now that gCling is set up. It is needed for // static initialization in these transactions through local_cxa_atexit(). for (llvm::SmallVectorImpl<Transaction*>::const_iterator I = IncrParserTransactions.begin(), E = IncrParserTransactions.end(); I != E; ++I) m_IncrParser->commitTransaction(*I); //setCallbacks(new AutoloadCallback(this)); }