- // If we got here fullpath is the path to the file, and its readable.
- set.insert(fullpath);
-
- // If its an LLVM bytecode file ...
- if (CheckMagic(fullpath, "llvm")) {
- // Process the dependent libraries recursively
- Module::LibraryListType modlibs;
- if (GetBytecodeDependentLibraries(fullpath,modlibs)) {
- // Traverse the dependent libraries list
- Module::lib_iterator LI = modlibs.begin();
- Module::lib_iterator LE = modlibs.end();
- while ( LI != LE ) {
- if (!ProcessLinkageItem(*LI,set,err)) {
- if (err.empty()) {
- err = std::string("Library '") + *LI +
- "' is not valid for linking but is required by file '" +
- fullpath + "'";
- } else {
- err += " which is required by file '" + fullpath + "'";
+ Action* GetAction(ConfigData* cd,
+ const sys::Path& input,
+ const sys::Path& output,
+ Phases phase)
+ {
+ Action* pat = 0; ///< The pattern/template for the action
+ Action* action = new Action; ///< The actual action to execute
+
+ // Get the action pattern
+ switch (phase) {
+ case PREPROCESSING: pat = &cd->PreProcessor; break;
+ case TRANSLATION: pat = &cd->Translator; break;
+ case OPTIMIZATION: pat = &cd->Optimizer; break;
+ case ASSEMBLY: pat = &cd->Assembler; break;
+ case LINKING: pat = &cd->Linker; break;
+ default:
+ assert(!"Invalid driver phase!");
+ break;
+ }
+ assert(pat != 0 && "Invalid command pattern");
+
+ // Copy over some pattern things that don't need to change
+ action->program = pat->program;
+ action->flags = pat->flags;
+
+ // Do the substitutions from the pattern to the actual
+ StringVector::iterator PI = pat->args.begin();
+ StringVector::iterator PE = pat->args.end();
+ while (PI != PE) {
+ if ((*PI)[0] == '%' && PI->length() >2) {
+ bool found = true;
+ switch ((*PI)[1]) {
+ case 'a':
+ if (*PI == "%args%") {
+ if (AdditionalArgs.size() > unsigned(phase))
+ if (!AdditionalArgs[phase].empty()) {
+ // Get specific options for each kind of action type
+ StringVector& addargs = AdditionalArgs[phase];
+ // Add specific options for each kind of action type
+ action->args.insert(action->args.end(), addargs.begin(),
+ addargs.end());
+ }
+ } else
+ found = false;
+ break;
+ case 'd':
+ if (*PI == "%defs%") {
+ StringVector::iterator I = Defines.begin();
+ StringVector::iterator E = Defines.end();
+ while (I != E) {
+ action->args.push_back( std::string("-D") + *I);
+ ++I;
+ }
+ } else
+ found = false;
+ break;
+ case 'f':
+ if (*PI == "%fOpts%") {
+ if (!fOptions.empty())
+ action->args.insert(action->args.end(), fOptions.begin(),
+ fOptions.end());
+ } else
+ found = false;
+ break;
+ case 'i':
+ if (*PI == "%in%") {
+ action->args.push_back(input.toString());
+ } else if (*PI == "%incls%") {
+ PathVector::iterator I = IncludePaths.begin();
+ PathVector::iterator E = IncludePaths.end();
+ while (I != E) {
+ action->args.push_back( std::string("-I") + I->toString() );
+ ++I;
+ }
+ } else
+ found = false;
+ break;
+ case 'l':
+ if (*PI == "%libs%") {
+ PathVector::iterator I = LibraryPaths.begin();
+ PathVector::iterator E = LibraryPaths.end();
+ while (I != E) {
+ action->args.push_back( std::string("-L") + I->toString() );
+ ++I;
+ }
+ } else
+ found = false;
+ break;
+ case 'o':
+ if (*PI == "%out%") {
+ action->args.push_back(output.toString());
+ } else if (*PI == "%opt%") {
+ if (!isSet(EMIT_RAW_FLAG)) {
+ if (cd->opts.size() > static_cast<unsigned>(optLevel) &&
+ !cd->opts[optLevel].empty())
+ action->args.insert(action->args.end(),
+ cd->opts[optLevel].begin(),
+ cd->opts[optLevel].end());
+ else
+ throw std::string("Optimization options for level ") +
+ utostr(unsigned(optLevel)) + " were not specified";
+ }
+ } else
+ found = false;
+ break;
+ case 's':
+ if (*PI == "%stats%") {
+ if (isSet(SHOW_STATS_FLAG))
+ action->args.push_back("-stats");
+ } else
+ found = false;
+ break;
+ case 't':
+ if (*PI == "%target%") {
+ action->args.push_back(std::string("-march=") + machine);
+ } else if (*PI == "%time%") {
+ if (isSet(TIME_PASSES_FLAG))
+ action->args.push_back("-time-passes");
+ } else
+ found = false;
+ break;
+ case 'v':
+ if (*PI == "%verbose%") {
+ if (isSet(VERBOSE_FLAG))
+ action->args.push_back("-v");
+ } else
+ found = false;
+ break;
+ case 'M':
+ if (*PI == "%Mopts%") {
+ if (!MOptions.empty())
+ action->args.insert(action->args.end(), MOptions.begin(),
+ MOptions.end());
+ } else
+ found = false;
+ break;
+ case 'W':
+ if (*PI == "%Wopts%") {
+ for (StringVector::iterator I = WOptions.begin(),
+ E = WOptions.end(); I != E ; ++I ) {
+ action->args.push_back( std::string("-W") + *I );
+ }
+ } else
+ found = false;
+ break;
+ default:
+ found = false;
+ break;
+ }
+ if (!found) {
+ // Did it even look like a substitution?
+ if (PI->length()>1 && (*PI)[0] == '%' &&
+ (*PI)[PI->length()-1] == '%') {
+ throw std::string("Invalid substitution token: '") + *PI +
+ "' for command '" + pat->program.toString() + "'";
+ } else if (!PI->empty()) {
+ // It's not a legal substitution, just pass it through
+ action->args.push_back(*PI);