diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/ant/Scalac.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Settings.scala | 42 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/TailCalls.scala | 20 |
4 files changed, 66 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala index 0db460b084..7a3d233aba 100644 --- a/src/compiler/scala/tools/ant/Scalac.scala +++ b/src/compiler/scala/tools/ant/Scalac.scala @@ -43,7 +43,7 @@ package scala.tools.ant { * <li>logging,</li> * <li>logphase,</li> * <li>usepredefs,</li> - * <li>debugcode,</li> + * <li>debuginfo,</li> * <li>addparams.</li> * </ul> * It also takes the following parameters as nested elements:<ul> @@ -123,7 +123,7 @@ package scala.tools.ant { /** Whether to use implicit predefined values or not. */ private var usepredefs: Boolean = true; /** Instruct the compiler to generate debugging information */ - private var debugCode: Boolean = false + private var debugInfo: String = "line" /** Instruct the compiler to generate debugging information */ private var addParams: String = "" @@ -272,8 +272,8 @@ package scala.tools.ant { usepredefs = input; /** Set the debug info attribute. */ - def setDebugCode(input: Boolean): Unit = - debugCode = input + def setDebuginfo(input: String): Unit = + debugInfo = input /** Set the debug info attribute. */ def setAddparams(input: String): Unit = @@ -460,7 +460,7 @@ package scala.tools.ant { } if (!logPhase.isEmpty) settings.log.value = logPhase settings.nopredefs.value = !usepredefs; - settings.debuginfo.value = debugCode + settings.debuginfo.value = debugInfo; log("Scalac params = '" + addParams + "'", Project.MSG_DEBUG) var args = diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index c6128486ae..28b0b2bb1a 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -74,7 +74,7 @@ class Settings(error: String => unit) { private val documenttitleDefault = "Scala 2" val doc = BooleanSetting("-doc", "Generate documentation"); - val debuginfo = BooleanSetting("-g", "Generate debugging info") + val debuginfo = new DebugSetting("-g", "Generate debugging info", List("none", "source", "line", "vars", "notc"), "line", "vars") val nowarnings = BooleanSetting("-nowarn", "Generate no warnings") val noassertions = BooleanSetting("-noassert", "Generate no assertions and assumptions") val verbose = BooleanSetting("-verbose", "Output messages about what the compiler is doing") @@ -211,7 +211,7 @@ class Settings(error: String => unit) { extends Setting(nme, descr + choices.mkString(" (", ",", ")")) { var value: String = default - private def argument: String = name.substring(1) + protected def argument: String = name.substring(1) def tryToSet(args: List[String]): List[String] = args match { case n :: rest if (n startsWith (name + ":")) => @@ -236,6 +236,44 @@ class Settings(error: String => unit) { else List(name + ":" + value) } + /** Same as ChoiceSetting but have a 'level' int which tells the index of the selected + * choice. The 'defaultEmpty' is used when this setting is used without specifying any of + * the available choices. + */ + class DebugSetting(nme: String, descr: String, choices: List[String], default: String, defaultEmpty: String) + extends ChoiceSetting(nme, descr, choices, default) { + + def indexOf[a](xs: List[a], e: a): Option[Int] = xs match { + case y :: ys => if (e == y) Some(0) else indexOf(ys, e) match { + case Some(idx) => Some(1 + idx) + case None => None + } + case _ => None; + } + var level: Int = indexOf(choices, default).get; + + override def tryToSet(args: List[String]): List[String] = args match { + case n :: rest if (n startsWith (name + ":")) => + val choice = n.substring(name.length() + 1) + if (!(choices contains choice)) { + error( + if (choice == "") "missing " + argument + else "unknown " + argument + " '" + choice + "'") + args + } else { + value = choice + level = indexOf(choices, choice).get; + rest + } + + case n :: rest if (n startsWith name) => + value = defaultEmpty; + level = indexOf(choices, defaultEmpty).get; + rest + + case _ => args + } + } /** A setting represented by a list of strings which should be prefixes of * phase names. This is not checked here, however. diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 348565b72e..eedf108b36 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -85,6 +85,10 @@ abstract class GenJVM extends SubComponent { val fjbgContext = if (settings.target.value == "jvm-1.5") new FJBGContext(49, 0) else new FJBGContext(); + val emitSource = settings.debuginfo.level >= 1; + val emitLines = settings.debuginfo.level >= 2; + val emitVars = settings.debuginfo.level >= 3; + def emitClass(jclass: JClass, sym: Symbol): Unit = { def addScalaAttr(sym: Symbol): Unit = currentRun.symData.get(sym) match { case Some(pickle) => @@ -386,7 +390,8 @@ abstract class GenJVM extends SubComponent { jcode = jmethod.getCode().asInstanceOf[JExtendedCode]; genCode(m); - genLocalVariableTable; + if (emitVars) + genLocalVariableTable; } addExceptionsAttribute(m.symbol) @@ -1224,7 +1229,7 @@ abstract class GenJVM extends SubComponent { private def genLocalVariableTable: Unit = { val vars: Array[JLocalVariable] = jmethod.getLocalVariables(); - if (!settings.debuginfo.value || vars.length == 0) + if (vars.length == 0) return; val pool = jclass.getConstantPool(); diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index c2681b2d3b..ccd1acebca 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -21,6 +21,17 @@ abstract class TailCalls extends Transform val phaseName: String = "tailcalls"; def newTransformer(unit: CompilationUnit): Transformer = new TailCallElimination(unit); + /** Create a new phase which applies transformer */ + override def newPhase(prev: scala.tools.nsc.Phase): StdPhase = new Phase(prev); + + /** The phase defined by this transform */ + class Phase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) { + def apply(unit: global.CompilationUnit): unit = if (!(settings.debuginfo.value == "notc")) { + newTransformer(unit).transformUnit(unit); + } + } + + /** * A Tail Call Transformer * @@ -138,8 +149,6 @@ abstract class TailCalls extends Transform newCtx.tparams = tparams map (.symbol); newCtx.label.setInfo( restpe.substSym(tpes, tparams map (.symbol))); - log("adding types: " + newCtx.tparams); - log("setting return resultType to: " + newCtx.label.tpe); case _ => (); } @@ -156,8 +165,6 @@ abstract class TailCalls extends Transform } else copy.DefDef(tree, mods, name, tparams, vparams, tpt, newRHS); } else { - log("Non-final method: " + name); - // Martin: OK like that? copy.DefDef(tree, mods, name, tparams, vparams, tpt, transform(rhs, newCtx)) } log("Leaving DefDef: " + name); @@ -199,7 +206,9 @@ abstract class TailCalls extends Transform case If(cond, thenp, elsep) => copy.If(tree, cond, transform(thenp), transform(elsep)); - case Match(selector, cases) => super.transform(tree); + case Match(selector, cases) => //super.transform(tree); + copy.Match(tree, transform(selector, mkContext(ctx, false)), transformTrees(cases).asInstanceOf[List[CaseDef]]); + case Return(expr) => super.transform(tree); case Try(block, catches, finalizer) => super.transform(tree); @@ -258,7 +267,6 @@ abstract class TailCalls extends Transform private def isSameTypes(ts1: List[Symbol], ts2: List[Symbol]): Boolean = { def isSameType(t1: Symbol, t2: Symbol) = { - log("" + t1 + " vs " + t2); t1 == t2 } List.forall2(ts1, ts2)(isSameType) |