[cfe-commits] r154105 - in /cfe/trunk: docs/ include/clang/Lex/ lib/Lex/ test/Preprocessor/ test/Preprocessor/Inputs/ test/Preprocessor/Inputs/TestFramework.framework/ test/Preprocessor/Inputs/TestFramework.framework/Frameworks/ test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/ test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/Headers/ test/Preprocessor/Inputs/TestFramework.framework/Headers/

Daniel Dunbar daniel at zuster.org
Thu Apr 5 10:10:07 PDT 2012


Author: ddunbar
Date: Thu Apr  5 12:10:06 2012
New Revision: 154105

URL: http://llvm.org/viewvc/llvm-project?rev=154105&view=rev
Log:
[Lex] Add support for 'user specified system frameworks' (see test case).
 - Developers of system frameworks need a way for their framework to be treated as a "system framework" during development. Otherwise, they are unable to properly test how their framework behaves when installed because of the semantic changes (in warning behavior) applied to system frameworks.

Added:
    cfe/trunk/test/Preprocessor/Inputs/
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/.system_framework
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/Headers/
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/Headers/AnotherTestFramework.h
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Headers/
    cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Headers/TestFramework.h
    cfe/trunk/test/Preprocessor/user_defined_system_framework.c
Modified:
    cfe/trunk/docs/LanguageExtensions.html
    cfe/trunk/include/clang/Lex/DirectoryLookup.h
    cfe/trunk/include/clang/Lex/HeaderSearch.h
    cfe/trunk/lib/Lex/HeaderSearch.cpp

Modified: cfe/trunk/docs/LanguageExtensions.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.html?rev=154105&r1=154104&r2=154105&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.html (original)
+++ cfe/trunk/docs/LanguageExtensions.html Thu Apr  5 12:10:06 2012
@@ -30,6 +30,7 @@
 <li><a href="#vectors">Vectors and Extended Vectors</a></li>
 <li><a href="#deprecated">Messages on <tt>deprecated</tt> and <tt>unavailable</tt> attributes</a></li>
 <li><a href="#attributes-on-enumerators">Attributes on enumerators</a></li>
+<li><a href="#user_specified_system_framework">'User-Specified' System Frameworks</a></li>
 <li><a href="#availability">Availability attribute</a></li>
 <li><a href="#checking_language_features">Checks for Standard Language Features</a>
   <ul>
@@ -626,6 +627,34 @@
 <p>Query for this feature with <tt>__has_extension(enumerator_attributes)</tt>.</p>
 
 <!-- ======================================================================= -->
+<h2 id="user_specified_system_framework">'User-Specified' System Frameworks</h2>
+<!-- ======================================================================= -->
+
+<p>Clang provides a mechanism by which frameworks can be built in such a way
+that they will always be treated as being 'system frameworks', even if they are
+not present in a system framework directory. This can be useful to system
+framework developers who want to be able to test building other applications
+with development builds of their framework, including the manner in which the
+compiler changes warning behavior for system headers.</p>
+
+<p>Framework developers can opt-in to this mechanism by creating a
+'.system_framework' file at the top-level of their framework. That is, the
+framework should have contents like:</p>
+
+<pre>
+ .../TestFramework.framework
+ .../TestFramework.framework/.system_framework
+ .../TestFramework.framework/Headers
+ .../TestFramework.framework/Headers/TestFramework.h
+ ...
+</pre>
+
+<p>Clang will treat the presence of this file as an indicator that the framework
+should be treated as a system framework, regardless of how it was found in the
+framework search path. For consistency, we recommend that such files never be
+included in installed versions of the framework.</p>
+
+<!-- ======================================================================= -->
 <h2 id="availability">Availability attribute</h2
 <!-- ======================================================================= -->
 

Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=154105&r1=154104&r2=154105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Thu Apr  5 12:10:06 2012
@@ -145,17 +145,23 @@
   /// \param SuggestedModule If non-null, and the file found is semantically
   /// part of a known module, this will be set to the module that should
   /// be imported instead of preprocessing/parsing the file found.
+  ///
+  /// \param InUserSpecifiedSystemHeader [out] If the file is found, set to true
+  /// if the file is located in a framework that has been user-specified to be
+  /// treated as a system framework.
   const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
                               SmallVectorImpl<char> *SearchPath,
                               SmallVectorImpl<char> *RelativePath,
-                              Module **SuggestedModule) const;
+                              Module **SuggestedModule,
+                              bool &InUserSpecifiedSystemHeader) const;
 
 private:
   const FileEntry *DoFrameworkLookup(
       StringRef Filename, HeaderSearch &HS,
       SmallVectorImpl<char> *SearchPath,
       SmallVectorImpl<char> *RelativePath,
-      Module **SuggestedModule) const;
+      Module **SuggestedModule,
+      bool &InUserSpecifiedSystemHeader) const;
 
 };
 

Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=154105&r1=154104&r2=154105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Thu Apr  5 12:10:06 2012
@@ -124,6 +124,11 @@
   struct FrameworkCacheEntry {
     /// The directory entry which should be used for the cached framework.
     const DirectoryEntry *Directory;
+
+    /// Whether this framework has been "user-specified" to be treated as if it
+    /// were a system framework (even if it was found outside a system framework
+    /// directory).
+    bool IsUserSpecifiedSystemFramework;
   };
 
   FileManager &FileMgr;

Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=154105&r1=154104&r2=154105&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Thu Apr  5 12:10:06 2012
@@ -204,7 +204,10 @@
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
-    Module **SuggestedModule) const {
+    Module **SuggestedModule,
+    bool &InUserSpecifiedSystemFramework) const {
+  InUserSpecifiedSystemFramework = false;
+
   SmallString<1024> TmpDir;
   if (isNormalDir()) {
     // Concatenate the requested file onto the directory.
@@ -239,7 +242,7 @@
 
   if (isFramework())
     return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
-                             SuggestedModule);
+                             SuggestedModule, InUserSpecifiedSystemFramework);
 
   assert(isHeaderMap() && "Unknown directory lookup");
   const FileEntry * const Result = getHeaderMap()->LookupFile(
@@ -266,7 +269,8 @@
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
-    Module **SuggestedModule) const 
+    Module **SuggestedModule,
+    bool &InUserSpecifiedSystemFramework) const
 {
   FileManager &FileMgr = HS.getFileMgr();
 
@@ -303,15 +307,27 @@
     HS.IncrementFrameworkLookupCount();
 
     // If the framework dir doesn't exist, we fail.
-    // FIXME: It's probably more efficient to query this with FileMgr.getDir.
-    if (!llvm::sys::fs::exists(FrameworkName.str()))
-      return 0;
+    const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
+    if (Dir == 0) return 0;
 
     // Otherwise, if it does, remember that this is the right direntry for this
     // framework.
     CacheEntry.Directory = getFrameworkDir();
+
+    // If this is a user search directory, check if the framework has been
+    // user-specified as a system framework.
+    if (getDirCharacteristic() == SrcMgr::C_User) {
+      SmallString<1024> SystemFrameworkMarker(FrameworkName);
+      SystemFrameworkMarker += ".system_framework";
+      if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) {
+        CacheEntry.IsUserSpecifiedSystemFramework = true;
+      }
+    }
   }
 
+  // Set the 'user-specified system framework' flag.
+  InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
+
   if (RelativePath != NULL) {
     RelativePath->clear();
     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
@@ -476,9 +492,10 @@
 
   // Check each directory in sequence to see if it contains this file.
   for (; i != SearchDirs.size(); ++i) {
+    bool InUserSpecifiedSystemFramework = false;
     const FileEntry *FE =
       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
-                               SuggestedModule);
+                               SuggestedModule, InUserSpecifiedSystemFramework);
     if (!FE) continue;
 
     CurDir = &SearchDirs[i];
@@ -487,6 +504,12 @@
     HeaderFileInfo &HFI = getFileInfo(FE);
     HFI.DirInfo = CurDir->getDirCharacteristic();
 
+    // If the directory characteristic is User but this framework was
+    // user-specified to be treated as a system framework, promote the
+    // characteristic.
+    if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
+      HFI.DirInfo = SrcMgr::C_System;
+
     // If this file is found in a header map and uses the framework style of
     // includes, then this header is part of a framework we're building.
     if (CurDir->isIndexHeaderMap()) {

Added: cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/.system_framework
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/.system_framework?rev=154105&view=auto
==============================================================================
    (empty)

Added: cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/Headers/AnotherTestFramework.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/Headers/AnotherTestFramework.h?rev=154105&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/Headers/AnotherTestFramework.h (added)
+++ cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Frameworks/AnotherTestFramework.framework/Headers/AnotherTestFramework.h Thu Apr  5 12:10:06 2012
@@ -0,0 +1,3 @@
+static inline int another_test_framework_func(unsigned a) {
+  return a;
+}

Added: cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Headers/TestFramework.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Headers/TestFramework.h?rev=154105&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Headers/TestFramework.h (added)
+++ cfe/trunk/test/Preprocessor/Inputs/TestFramework.framework/Headers/TestFramework.h Thu Apr  5 12:10:06 2012
@@ -0,0 +1,6 @@
+// Include a subframework header.
+#include <AnotherTestFramework/AnotherTestFramework.h>
+
+static inline int test_framework_func(unsigned a) {
+  return a;
+}

Added: cfe/trunk/test/Preprocessor/user_defined_system_framework.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/user_defined_system_framework.c?rev=154105&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/user_defined_system_framework.c (added)
+++ cfe/trunk/test/Preprocessor/user_defined_system_framework.c Thu Apr  5 12:10:06 2012
@@ -0,0 +1,8 @@
+// RUN: %clang -cc1 -fsyntax-only -F %S/Inputs -Wsign-conversion -verify %s
+
+// Check that TestFramework is treated as a system header.
+#include <TestFramework/TestFramework.h>
+
+int f1() {
+  return test_framework_func(1) + another_test_framework_func(2);
+}





More information about the cfe-commits mailing list