am 74a4b082: Fix pass-by-value when the return type uses pass-by-reference.

* commit '74a4b08235990916911b8fe758d656c1171faf26':
  Fix pass-by-value when the return type uses pass-by-reference.
diff --git a/include/bcc/AndroidBitcode/ABCCompilerDriver.h b/include/bcc/AndroidBitcode/ABCCompilerDriver.h
index 5f5ad7f..a740330 100644
--- a/include/bcc/AndroidBitcode/ABCCompilerDriver.h
+++ b/include/bcc/AndroidBitcode/ABCCompilerDriver.h
@@ -39,7 +39,6 @@
   CompilerConfig *mCompilerConfig;
   LinkerConfig *mLinkerConfig;
 
-  std::string mTriple;
   std::string mAndroidSysroot;
 
 private:
@@ -52,6 +51,10 @@
   bool link(const Script &pScript, const std::string &input_relocatable,
             int pOutputFd);
 
+private:
+  virtual CompilerConfig *createCompilerConfig() const = 0;
+  virtual LinkerConfig *createLinkerConfig() const = 0;
+
 protected:
   virtual const char **getNonPortableList() const {
     return NULL;
@@ -61,7 +64,7 @@
   virtual ABCExpandVAArgPass *createExpandVAArgPass() const = 0;
 
 protected:
-  ABCCompilerDriver(const std::string &pTriple);
+  ABCCompilerDriver();
 
 public:
   static ABCCompilerDriver *Create(const std::string &pTriple);
@@ -76,10 +79,6 @@
     mAndroidSysroot = pAndroidSysroot;
   }
 
-  inline const std::string &getTriple() const {
-    return mTriple;
-  }
-
   // Compile the bitcode and link the shared object
   bool build(int pInputFd, int pOutputFd);
 };
diff --git a/include/bcc/Support/TargetCompilerConfigs.h b/include/bcc/Support/TargetCompilerConfigs.h
index 181fd80..391a0eb 100644
--- a/include/bcc/Support/TargetCompilerConfigs.h
+++ b/include/bcc/Support/TargetCompilerConfigs.h
@@ -26,18 +26,39 @@
 // ARM
 //===----------------------------------------------------------------------===//
 #if defined(PROVIDE_ARM_CODEGEN)
-class ARMCompilerConfig : public CompilerConfig {
+class ARMBaseCompilerConfig : public CompilerConfig {
 private:
   bool mEnableNEON;
+  bool mInThumbMode;
+
+  static bool HasThumb2();
 
   static void GetFeatureVector(std::vector<std::string> &pAttributes,
-                               bool pEnableNEON);
+                               bool pInThumbMode, bool pEnableNEON);
+
+protected:
+  ARMBaseCompilerConfig(const std::string &pTriple, bool pInThumbMode);
 
 public:
-  ARMCompilerConfig();
-
   // Return true if config has been changed after returning from this function.
   bool enableNEON(bool pEnable = true);
+
+  bool isInThumbMode() const
+  { return mInThumbMode; }
+};
+
+class ARMCompilerConfig : public ARMBaseCompilerConfig {
+public:
+  ARMCompilerConfig()
+    : ARMBaseCompilerConfig(DEFAULT_ARM_TRIPLE_STRING,
+                            /* pInThumbMode */false) { }
+};
+
+class ThumbCompilerConfig : public ARMBaseCompilerConfig {
+public:
+  ThumbCompilerConfig()
+    : ARMBaseCompilerConfig(DEFAULT_THUMB_TRIPLE_STRING,
+                            /* pInThumbMode */true) { }
 };
 #endif // defined(PROVIDE_ARM_CODEGEN)
 
diff --git a/lib/AndroidBitcode/ABCCompilerDriver.cpp b/lib/AndroidBitcode/ABCCompilerDriver.cpp
index 4eb33e6..5be45ec 100644
--- a/lib/AndroidBitcode/ABCCompilerDriver.cpp
+++ b/lib/AndroidBitcode/ABCCompilerDriver.cpp
@@ -44,10 +44,9 @@
 
 namespace bcc {
 
-ABCCompilerDriver::ABCCompilerDriver(const std::string &pTriple)
+ABCCompilerDriver::ABCCompilerDriver()
   : mContext(), mCompiler(*this), mLinker(),
-    mCompilerConfig(NULL), mLinkerConfig(NULL),
-    mTriple(pTriple), mAndroidSysroot("/") {
+    mCompilerConfig(NULL), mLinkerConfig(NULL), mAndroidSysroot("/") {
 }
 
 ABCCompilerDriver::~ABCCompilerDriver() {
@@ -60,7 +59,7 @@
     return true;
   }
 
-  mCompilerConfig = new (std::nothrow) CompilerConfig(mTriple);
+  mCompilerConfig = createCompilerConfig();
   if (mCompilerConfig == NULL) {
     ALOGE("Out of memory when create the compiler configuration!");
     return false;
@@ -88,7 +87,7 @@
     return true;
   }
 
-  mLinkerConfig = new (std::nothrow) LinkerConfig(mTriple);
+  mLinkerConfig = createLinkerConfig();
   if (mLinkerConfig == NULL) {
     ALOGE("Out of memory when create the linker configuration!");
     return false;
@@ -230,19 +229,21 @@
 
   switch (llvm::Triple::getArchTypeForLLVMName(target->getName())) {
 #if defined(PROVIDE_ARM_CODEGEN)
-    case llvm::Triple::arm:
+    case llvm::Triple::arm: {
+      return new ARMABCCompilerDriver(/* pInThumbMode */false);
+    }
     case llvm::Triple::thumb: {
-      return new ARMABCCompilerDriver(pTriple);
+      return new ARMABCCompilerDriver(/* pInThumbMode */true);
     }
 #endif
 #if defined(PROVIDE_MIPS_CODEGEN)
     case llvm::Triple::mipsel: {
-      return new MipsABCCompilerDriver(pTriple);
+      return new MipsABCCompilerDriver();
     }
 #endif
 #if defined(PROVIDE_X86_CODEGEN)
     case llvm::Triple::x86: {
-      return new X86ABCCompilerDriver(pTriple);
+      return new X86ABCCompilerDriver();
     }
 #endif
     default: {
diff --git a/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.cpp b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.cpp
new file mode 100644
index 0000000..f019bde
--- /dev/null
+++ b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ARM/ARMABCCompilerDriver.h"
+
+#include "bcc/Support/TargetCompilerConfigs.h"
+#include "bcc/Support/TargetLinkerConfigs.h"
+
+namespace bcc {
+
+CompilerConfig *ARMABCCompilerDriver::createCompilerConfig() const {
+  if (mInThumbMode) {
+    return new (std::nothrow) ThumbCompilerConfig();
+  } else {
+    return new (std::nothrow) ARMCompilerConfig();
+  }
+}
+
+LinkerConfig *ARMABCCompilerDriver::createLinkerConfig() const {
+  return new (std::nothrow) ARMLinkerConfig();
+}
+
+} // end namespace bcc
diff --git a/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
index 29f4f0a..97e5f8d 100644
--- a/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
+++ b/lib/AndroidBitcode/ARM/ARMABCCompilerDriver.h
@@ -22,13 +22,24 @@
 namespace bcc {
 
 class ARMABCCompilerDriver : public ABCCompilerDriver {
+private:
+  bool mInThumbMode;
+
 public:
-  ARMABCCompilerDriver(const std::string &pTriple)
-      : ABCCompilerDriver(pTriple) { }
+  ARMABCCompilerDriver(bool pInThumbMode)
+    : ABCCompilerDriver(), mInThumbMode(pInThumbMode) { }
 
   virtual ~ARMABCCompilerDriver() { }
 
+public:
+  inline bool IsInThumbMode() const {
+    return mInThumbMode;
+  }
+
 private:
+  virtual CompilerConfig *createCompilerConfig() const;
+  virtual LinkerConfig *createLinkerConfig() const;
+
   virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
 };
 
diff --git a/lib/AndroidBitcode/Android.mk b/lib/AndroidBitcode/Android.mk
index 806202c..0befc55 100644
--- a/lib/AndroidBitcode/Android.mk
+++ b/lib/AndroidBitcode/Android.mk
@@ -27,6 +27,7 @@
   ABCCompilerDriver.cpp
 
 libbcc_arm_androidbitcode_SRC_FILES := \
+  ARM/ARMABCCompilerDriver.cpp \
   ARM/ARMABCExpandVAArg.cpp
 
 libbcc_mips_androidbitcode_SRC_FILES := \
diff --git a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
index 54b9d61..326920a 100644
--- a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
+++ b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.cpp
@@ -16,6 +16,9 @@
 
 #include "Mips/MipsABCCompilerDriver.h"
 
+#include "bcc/Support/TargetCompilerConfigs.h"
+#include "bcc/Support/TargetLinkerConfigs.h"
+
 namespace {
 
 static const char *MipsNonPortableList[] = {
@@ -37,6 +40,14 @@
 
 namespace bcc {
 
+CompilerConfig *MipsABCCompilerDriver::createCompilerConfig() const {
+  return new (std::nothrow) MipsCompilerConfig();
+}
+
+LinkerConfig *MipsABCCompilerDriver::createLinkerConfig() const {
+  return new (std::nothrow) MipsLinkerConfig();
+}
+
 const char **MipsABCCompilerDriver::getNonPortableList() const {
   return MipsNonPortableList;
 }
diff --git a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
index 7cfc34f..6cdecc5 100644
--- a/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
+++ b/lib/AndroidBitcode/Mips/MipsABCCompilerDriver.h
@@ -23,12 +23,14 @@
 
 class MipsABCCompilerDriver : public ABCCompilerDriver {
 public:
-  MipsABCCompilerDriver(const std::string &pTriple)
-      : ABCCompilerDriver(pTriple) { }
+  MipsABCCompilerDriver() : ABCCompilerDriver() { }
 
   virtual ~MipsABCCompilerDriver() { }
 
 private:
+  virtual CompilerConfig *createCompilerConfig() const;
+  virtual LinkerConfig *createLinkerConfig() const;
+
   virtual const char **getNonPortableList() const;
 
   virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
diff --git a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
index 171da7c..e8f0159 100644
--- a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
+++ b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.cpp
@@ -16,6 +16,9 @@
 
 #include "X86/X86ABCCompilerDriver.h"
 
+#include "bcc/Support/TargetCompilerConfigs.h"
+#include "bcc/Support/TargetLinkerConfigs.h"
+
 namespace {
 
 static const char *X86NonPortableList[] = {
@@ -36,6 +39,16 @@
 
 namespace bcc {
 
+CompilerConfig *X86ABCCompilerDriver::createCompilerConfig() const {
+  // x86-64 is currently unsupported.
+  return new (std::nothrow) X86_32CompilerConfig();
+}
+
+LinkerConfig *X86ABCCompilerDriver::createLinkerConfig() const {
+  // x86-64 is currently unsupported.
+  return new (std::nothrow) X86_32LinkerConfig();
+}
+
 const char **X86ABCCompilerDriver::getNonPortableList() const {
   return X86NonPortableList;
 }
diff --git a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
index af52866..aed2f56 100644
--- a/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
+++ b/lib/AndroidBitcode/X86/X86ABCCompilerDriver.h
@@ -23,12 +23,14 @@
 
 class X86ABCCompilerDriver : public ABCCompilerDriver {
 public:
-  X86ABCCompilerDriver(const std::string &pTriple)
-      : ABCCompilerDriver(pTriple) { }
+  X86ABCCompilerDriver() : ABCCompilerDriver() { }
 
   virtual ~X86ABCCompilerDriver() { }
 
 private:
+  virtual CompilerConfig *createCompilerConfig() const;
+  virtual LinkerConfig *createLinkerConfig() const;
+
   virtual const char **getNonPortableList() const;
 
   virtual ABCExpandVAArgPass *createExpandVAArgPass() const;
diff --git a/lib/Support/TargetCompilerConfigs.cpp b/lib/Support/TargetCompilerConfigs.cpp
index df78637..2dcd173 100644
--- a/lib/Support/TargetCompilerConfigs.cpp
+++ b/lib/Support/TargetCompilerConfigs.cpp
@@ -16,6 +16,11 @@
 
 #include "bcc/Support/TargetCompilerConfigs.h"
 
+// Get ARM version number (i.e., __ARM_ARCH__)
+#ifdef __arm__
+#include <machine/cpu-features.h>
+#endif
+
 using namespace bcc;
 
 //===----------------------------------------------------------------------===//
@@ -23,8 +28,28 @@
 //===----------------------------------------------------------------------===//
 #if defined(PROVIDE_ARM_CODEGEN)
 
-void ARMCompilerConfig::GetFeatureVector(std::vector<std::string> &pAttributes,
-                                         bool pEnableNEON) {
+bool ARMBaseCompilerConfig::HasThumb2() {
+#if !defined(TARGET_BUILD)
+  // Cross-compiler can always generate Thumb-2 instructions.
+  return true;
+#else // defined(TARGET_BUILD)
+#  if defined(ARCH_ARM_HAVE_THUMB_SUPPORT)
+#    if (__ARM_ARCH__ >= 7) || defined(__ARM_ARCH_6T2__)
+  return true;
+#    else
+  // ARM prior to V6T2 doesn't support Thumb-2.
+  return false;
+#    endif
+#  else // !defined(ARCH_ARM_HAVE_THUMB_SUPPORT)
+  // Target that doesn't support Thumb feature won't support Thumb-2, either.
+  return false;
+#  endif
+#endif
+}
+
+void
+ARMBaseCompilerConfig::GetFeatureVector(std::vector<std::string> &pAttributes,
+                                        bool pInThumbMode, bool pEnableNEON) {
 #if defined(ARCH_ARM_HAVE_VFP)
   pAttributes.push_back("+vfp3");
 #  if !defined(ARCH_ARM_HAVE_VFP_D32)
@@ -32,6 +57,14 @@
 #  endif
 #endif
 
+  if (pInThumbMode) {
+    if (HasThumb2()) {
+      pAttributes.push_back("+thumb2");
+    } else {
+      pAttributes.push_back("-thumb2");
+    }
+  }
+
 #if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_ARCH_ARM_HAVE_NEON)
   if (pEnableNEON) {
     pAttributes.push_back("+neon");
@@ -48,24 +81,25 @@
   return;
 }
 
-ARMCompilerConfig::ARMCompilerConfig()
-  : CompilerConfig(DEFAULT_ARM_TRIPLE_STRING) {
+ARMBaseCompilerConfig::ARMBaseCompilerConfig(const std::string &pTriple,
+                                             bool pInThumbMode)
+  : CompilerConfig(pTriple), mInThumbMode(pInThumbMode) {
 
   // Enable NEON by default.
   mEnableNEON = true;
 
   std::vector<std::string> attributes;
-  GetFeatureVector(attributes, /* pEnableNEON */mEnableNEON);
+  GetFeatureVector(attributes, mInThumbMode, mEnableNEON);
   setFeatureString(attributes);
 
   return;
 }
 
-bool ARMCompilerConfig::enableNEON(bool pEnable) {
+bool ARMBaseCompilerConfig::enableNEON(bool pEnable) {
 #if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_ARCH_ARM_HAVE_NEON)
   if (mEnableNEON != pEnable) {
     std::vector<std::string> attributes;
-    GetFeatureVector(attributes, pEnable);
+    GetFeatureVector(attributes, mInThumbMode, pEnable);
     setFeatureString(attributes);
     mEnableNEON = pEnable;
     return true;
diff --git a/tools/abcc/Main.cpp b/tools/abcc/Main.cpp
index 44ceadd..d783ca9 100644
--- a/tools/abcc/Main.cpp
+++ b/tools/abcc/Main.cpp
@@ -102,7 +102,12 @@
 #endif
 
   if (triple == NULL) {
-    triple = DEFAULT_TARGET_TRIPLE_STRING;
+#ifdef DEFAULT_ARM_CODEGEN
+    // Generate Thumb instead of ARM.
+    triple = DEFAULT_THUMB_TRIPLE_STRING;
+#else
+     triple = DEFAULT_TARGET_TRIPLE_STRING;
+#endif
   }
 
   if (sysroot == NULL) {
diff --git a/tools/bcc/Android.mk b/tools/bcc/Android.mk
index 6f95eec..0799c61 100644
--- a/tools/bcc/Android.mk
+++ b/tools/bcc/Android.mk
@@ -45,7 +45,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := bcc
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := EXECUTABLES
 
 LOCAL_SRC_FILES := Main.cpp
diff --git a/tools/mcld/Android.mk b/tools/mcld/Android.mk
index b8213d0..3e53c42 100644
--- a/tools/mcld/Android.mk
+++ b/tools/mcld/Android.mk
@@ -21,7 +21,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := mcld
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := EXECUTABLES
 
 LOCAL_SRC_FILES := Main.cpp
@@ -40,7 +39,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := mcld
-LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := EXECUTABLES
 
 LOCAL_SRC_FILES := Main.cpp