[cfe-commits] r165821 - in /cfe/trunk: lib/Lex/ModuleMap.cpp test/Modules/Inputs/normal-module-map/nested_umbrella/1.h test/Modules/Inputs/normal-module-map/nested_umbrella/a-extras.h test/Modules/normal-module-map.cpp
Douglas Gregor
dgregor at apple.com
Fri Oct 12 14:15:51 PDT 2012
Author: dgregor
Date: Fri Oct 12 16:15:50 2012
New Revision: 165821
URL: http://llvm.org/viewvc/llvm-project?rev=165821&view=rev
Log:
Sanitize the names of modules determined based on the names of headers
or directories, to make sure that they are identifiers that are not
keywords in any dialect. Fixes <rdar://problem/12489495>.
Added:
cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/1.h
cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/a-extras.h
Modified:
cfe/trunk/lib/Lex/ModuleMap.cpp
cfe/trunk/test/Modules/normal-module-map.cpp
Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=165821&r1=165820&r2=165821&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Fri Oct 12 16:15:50 2012
@@ -97,6 +97,54 @@
this->Target = &Target;
}
+/// \brief "Sanitize" a filename so that it can be used as an identifier.
+static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
+ SmallVectorImpl<char> &Buffer) {
+ if (Name.empty())
+ return Name;
+
+ // Check whether the filename is already an identifier; this is the common
+ // case.
+ bool isIdentifier = true;
+ for (unsigned I = 0, N = Name.size(); I != N; ++I) {
+ if (isalpha(Name[I]) || Name[I] == '_' || (isdigit(Name[I]) && I > 0))
+ continue;
+
+ isIdentifier = false;
+ break;
+ }
+
+ if (!isIdentifier) {
+ // If we don't already have something with the form of an identifier,
+ // create a buffer with the sanitized name.
+ Buffer.clear();
+ if (isdigit(Name[0]))
+ Buffer.push_back('_');
+ Buffer.reserve(Buffer.size() + Name.size());
+ for (unsigned I = 0, N = Name.size(); I != N; ++I) {
+ if (isalnum(Name[I]) || isspace(Name[I]))
+ Buffer.push_back(Name[I]);
+ else
+ Buffer.push_back('_');
+ }
+
+ Name = StringRef(Buffer.data(), Buffer.size());
+ }
+
+ while (llvm::StringSwitch<bool>(Name)
+#define KEYWORD(Keyword,Conditions) .Case(#Keyword, true)
+#define ALIAS(Keyword, AliasOf, Conditions) .Case(Keyword, true)
+#include "clang/Basic/TokenKinds.def"
+ .Default(false)) {
+ if (Name.data() != Buffer.data())
+ Buffer.append(Name.begin(), Name.end());
+ Buffer.push_back('_');
+ Name = StringRef(Buffer.data(), Buffer.size());
+ }
+
+ return Name;
+}
+
Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
llvm::DenseMap<const FileEntry *, Module *>::iterator Known
= Headers.find(File);
@@ -135,7 +183,10 @@
for (unsigned I = SkippedDirs.size(); I != 0; --I) {
// Find or create the module that corresponds to this directory name.
- StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
+ SmallString<32> NameBuf;
+ StringRef Name = sanitizeFilenameAsIdentifier(
+ llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
+ NameBuf);
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Explicit).first;
@@ -149,7 +200,9 @@
}
// Infer a submodule with the same name as this header file.
- StringRef Name = llvm::sys::path::stem(File->getName());
+ SmallString<32> NameBuf;
+ StringRef Name = sanitizeFilenameAsIdentifier(
+ llvm::sys::path::stem(File->getName()), NameBuf);
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
Explicit).first;
Result->TopHeaders.insert(File);
@@ -218,7 +271,10 @@
if (UmbrellaModule->InferSubmodules) {
for (unsigned I = SkippedDirs.size(); I != 0; --I) {
// Find or create the module that corresponds to this directory name.
- StringRef Name = llvm::sys::path::stem(SkippedDirs[I-1]->getName());
+ SmallString<32> NameBuf;
+ StringRef Name = sanitizeFilenameAsIdentifier(
+ llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
+ NameBuf);
Found = lookupModuleQualified(Name, Found);
if (!Found)
return false;
@@ -227,7 +283,10 @@
}
// Infer a submodule with the same name as this header file.
- StringRef Name = llvm::sys::path::stem(Header->getName());
+ SmallString<32> NameBuf;
+ StringRef Name = sanitizeFilenameAsIdentifier(
+ llvm::sys::path::stem(Header->getName()),
+ NameBuf);
Found = lookupModuleQualified(Name, Found);
if (!Found)
return false;
@@ -377,8 +436,10 @@
#endif
// FIXME: Do we want to warn about subframeworks without umbrella headers?
- inferFrameworkModule(llvm::sys::path::stem(Dir->path()), SubframeworkDir,
- IsSystem, Result);
+ SmallString<32> NameBuf;
+ inferFrameworkModule(sanitizeFilenameAsIdentifier(
+ llvm::sys::path::stem(Dir->path()), NameBuf),
+ SubframeworkDir, IsSystem, Result);
}
}
Added: cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/1.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/1.h?rev=165821&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/1.h (added)
+++ cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/1.h Fri Oct 12 16:15:50 2012
@@ -0,0 +1 @@
+int one;
Added: cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/a-extras.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/a-extras.h?rev=165821&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/a-extras.h (added)
+++ cfe/trunk/test/Modules/Inputs/normal-module-map/nested_umbrella/a-extras.h Fri Oct 12 16:15:50 2012
@@ -0,0 +1 @@
+int extra_a;
Modified: cfe/trunk/test/Modules/normal-module-map.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/normal-module-map.cpp?rev=165821&r1=165820&r2=165821&view=diff
==============================================================================
--- cfe/trunk/test/Modules/normal-module-map.cpp (original)
+++ cfe/trunk/test/Modules/normal-module-map.cpp Fri Oct 12 16:15:50 2012
@@ -33,3 +33,13 @@
int testNestedUmbrellaB() {
return nested_umbrella_b;
}
+
+ at __experimental_modules_import nested_umbrella.a_extras;
+
+ at __experimental_modules_import nested_umbrella._1;
+
+ at __experimental_modules_import nested_umbrella.decltype_;
+
+int testSanitizedName() {
+ return extra_a + one + decltype_val;
+}
More information about the cfe-commits
mailing list