summaryrefslogtreecommitdiffstats
path: root/lib/Frontend/InitHeaderSearch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/InitHeaderSearch.cpp')
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp157
1 files changed, 116 insertions, 41 deletions
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index d19ae98..a40a569 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -170,9 +170,8 @@ void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(const std::string &Base,
const char *Dir32,
const char *Dir64,
const llvm::Triple &triple) {
- // Add the common dirs
+ // Add the base dir
AddPath(Base, System, true, false, false);
- AddPath(Base + "/backward", System, true, false, false);
// Add the multilib dirs
llvm::Triple::ArchType arch = triple.getArch();
@@ -181,6 +180,9 @@ void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(const std::string &Base,
AddPath(Base + "/" + ArchDir + "/" + Dir64, System, true, false, false);
else
AddPath(Base + "/" + ArchDir + "/" + Dir32, System, true, false, false);
+
+ // Add the backward dir
+ AddPath(Base + "/backward", System, true, false, false);
}
void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(const std::string &Base,
@@ -194,7 +196,15 @@ void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(const std::string &Base,
// FIXME: This probably should goto to some platform utils place.
#ifdef _MSC_VER
+
// Read registry string.
+ // This also supports a means to look for high-versioned keys by use
+ // of a $VERSION placeholder in the key path.
+ // $VERSION in the key path is a placeholder for the version number,
+ // causing the highest value path to be searched for and used.
+ // I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
+ // There can be additional characters in the component. Only the numberic
+ // characters are compared.
bool getSystemRegistryString(const char *keyPath, const char *valueName,
char *value, size_t maxLength) {
HKEY hRootKey = NULL;
@@ -202,6 +212,7 @@ bool getSystemRegistryString(const char *keyPath, const char *valueName,
const char* subKey = NULL;
DWORD valueType;
DWORD valueSize = maxLength - 1;
+ long lResult;
bool returnValue = false;
if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
hRootKey = HKEY_CLASSES_ROOT;
@@ -221,13 +232,80 @@ bool getSystemRegistryString(const char *keyPath, const char *valueName,
}
else
return(false);
- long lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ, &hKey);
- if (lResult == ERROR_SUCCESS) {
- lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
- (LPBYTE)value, &valueSize);
- if (lResult == ERROR_SUCCESS)
- returnValue = true;
- RegCloseKey(hKey);
+ const char *placeHolder = strstr(subKey, "$VERSION");
+ char bestName[256];
+ bestName[0] = '\0';
+ // If we have a $VERSION placeholder, do the highest-version search.
+ if (placeHolder) {
+ const char *keyEnd = placeHolder - 1;
+ const char *nextKey = placeHolder;
+ // Find end of previous key.
+ while ((keyEnd > subKey) && (*keyEnd != '\\'))
+ keyEnd--;
+ // Find end of key containing $VERSION.
+ while (*nextKey && (*nextKey != '\\'))
+ nextKey++;
+ size_t partialKeyLength = keyEnd - subKey;
+ char partialKey[256];
+ if (partialKeyLength > sizeof(partialKey))
+ partialKeyLength = sizeof(partialKey);
+ strncpy(partialKey, subKey, partialKeyLength);
+ partialKey[partialKeyLength] = '\0';
+ HKEY hTopKey = NULL;
+ lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
+ if (lResult == ERROR_SUCCESS) {
+ char keyName[256];
+ int bestIndex = -1;
+ double bestValue = 0.0;
+ DWORD index, size = sizeof(keyName) - 1;
+ for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
+ NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
+ const char *sp = keyName;
+ while (*sp && !isdigit(*sp))
+ sp++;
+ if (!*sp)
+ continue;
+ const char *ep = sp + 1;
+ while (*ep && (isdigit(*ep) || (*ep == '.')))
+ ep++;
+ char numBuf[32];
+ strncpy(numBuf, sp, sizeof(numBuf) - 1);
+ numBuf[sizeof(numBuf) - 1] = '\0';
+ double value = strtod(numBuf, NULL);
+ if (value > bestValue) {
+ bestIndex = (int)index;
+ bestValue = value;
+ strcpy(bestName, keyName);
+ }
+ size = sizeof(keyName) - 1;
+ }
+ // If we found the highest versioned key, open the key and get the value.
+ if (bestIndex != -1) {
+ // Append rest of key.
+ strncat(bestName, nextKey, sizeof(bestName) - 1);
+ bestName[sizeof(bestName) - 1] = '\0';
+ // Open the chosen key path remainder.
+ lResult = RegOpenKeyEx(hTopKey, bestName, 0, KEY_READ, &hKey);
+ if (lResult == ERROR_SUCCESS) {
+ lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
+ (LPBYTE)value, &valueSize);
+ if (lResult == ERROR_SUCCESS)
+ returnValue = true;
+ RegCloseKey(hKey);
+ }
+ }
+ RegCloseKey(hTopKey);
+ }
+ }
+ else {
+ lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ, &hKey);
+ if (lResult == ERROR_SUCCESS) {
+ lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
+ (LPBYTE)value, &valueSize);
+ if (lResult == ERROR_SUCCESS)
+ returnValue = true;
+ RegCloseKey(hKey);
+ }
}
return(returnValue);
}
@@ -240,35 +318,13 @@ bool getSystemRegistryString(const char *, const char *, char *, size_t) {
// Get Visual Studio installation directory.
bool getVisualStudioDir(std::string &path) {
+ char vsIDEInstallDir[256];
// Try the Windows registry first.
- char vs80IDEInstallDir[256];
- char vs90IDEInstallDir[256];
- const char* vsIDEInstallDir = NULL;
- bool has80 = getSystemRegistryString(
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0",
- "InstallDir", vs80IDEInstallDir, sizeof(vs80IDEInstallDir) - 1);
- bool has90 = getSystemRegistryString(
- "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0",
- "InstallDir", vs90IDEInstallDir, sizeof(vs90IDEInstallDir) - 1);
+ bool hasVCDir = getSystemRegistryString(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
+ "InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
// If we have both vc80 and vc90, pick version we were compiled with.
- if (has80 && has90) {
- #ifdef _MSC_VER
- #if (_MSC_VER >= 1500) // VC90
- vsIDEInstallDir = vs90IDEInstallDir;
- #elif (_MSC_VER == 1400) // VC80
- vsIDEInstallDir = vs80IDEInstallDir;
- #else
- vsIDEInstallDir = vs90IDEInstallDir;
- #endif
- #else
- vsIDEInstallDir = vs90IDEInstallDir;
- #endif
- }
- else if (has90)
- vsIDEInstallDir = vs90IDEInstallDir;
- else if (has80)
- vsIDEInstallDir = vs80IDEInstallDir;
- if (vsIDEInstallDir && *vsIDEInstallDir) {
+ if (hasVCDir && vsIDEInstallDir[0]) {
char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
if (p)
*p = '\0';
@@ -307,6 +363,21 @@ bool getVisualStudioDir(std::string &path) {
return(false);
}
+ // Get Windows SDK installation directory.
+bool getWindowsSDKDir(std::string &path) {
+ char windowsSDKInstallDir[256];
+ // Try the Windows registry.
+ bool hasSDKDir = getSystemRegistryString(
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
+ "InstallationFolder", windowsSDKInstallDir, sizeof(windowsSDKInstallDir) - 1);
+ // If we have both vc80 and vc90, pick version we were compiled with.
+ if (hasSDKDir && windowsSDKInstallDir[0]) {
+ path = windowsSDKInstallDir;
+ return(true);
+ }
+ return(false);
+}
+
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) {
// FIXME: temporary hack: hard-coded paths.
llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS);
@@ -324,10 +395,14 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) {
case llvm::Triple::Win32:
{
std::string VSDir;
+ std::string WindowsSDKDir;
if (getVisualStudioDir(VSDir)) {
AddPath(VSDir + "\\VC\\include", System, false, false, false);
- AddPath(VSDir + "\\VC\\PlatformSDK\\Include",
- System, false, false, false);
+ if (getWindowsSDKDir(WindowsSDKDir))
+ AddPath(WindowsSDKDir, System, false, false, false);
+ else
+ AddPath(VSDir + "\\VC\\PlatformSDK\\Include",
+ System, false, false, false);
}
else {
// Default install paths.
@@ -489,6 +564,9 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl
void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,
const llvm::Triple &triple) {
+ if (Lang.CPlusPlus)
+ AddDefaultCPlusPlusIncludePaths(triple);
+
AddDefaultCIncludePaths(triple);
// Add the default framework include paths on Darwin.
@@ -496,9 +574,6 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,
AddPath("/System/Library/Frameworks", System, true, false, true);
AddPath("/Library/Frameworks", System, true, false, true);
}
-
- if (Lang.CPlusPlus)
- AddDefaultCPlusPlusIncludePaths(triple);
}
/// RemoveDuplicates - If there are duplicate directory entries in the specified
OpenPOWER on IntegriCloud