]> granicus.if.org Git - clang/commitdiff
make getFileCharacteristic linetable aware. line markers that
authorChris Lattner <sabre@nondot.org>
Wed, 4 Feb 2009 05:33:01 +0000 (05:33 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 4 Feb 2009 05:33:01 +0000 (05:33 +0000)
play around with the 'is system header' bit now function correctly.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63720 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/SourceManager.h
lib/Basic/SourceManager.cpp
test/Preprocessor/line-directive.c

index e24e62389952703ca423636577f7d0a7dac1e606..565cb0e17eb17f0c60eebeb480a31289104ce1e2 100644 (file)
@@ -495,11 +495,15 @@ public:
   unsigned getInstantiationLineNumber(SourceLocation Loc) const;
   unsigned getSpellingLineNumber(SourceLocation Loc) const;
   
-  // FIXME: This should handle #line.
-  SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const {
-    FileID FID = getFileID(getSpellingLoc(Loc));
-    return getSLocEntry(FID).getFile().getFileCharacteristic();
-  }
+  /// getFileCharacteristic - return the file characteristic of the specified
+  /// source location, indicating whether this is a normal file, a system 
+  /// header, or an "implicit extern C" system header.
+  ///
+  /// This state can be modified with flags on GNU linemarker directives like:
+  ///   # 4 "foo.h" 3
+  /// which changes all source locations in the current file after that to be
+  /// considered to be from a system header.
+  SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
   
   /// getPresumedLoc - This method returns the "presumed" location of a
   /// SourceLocation specifies.  A "presumed location" can be modified by #line
index 275d520e04473f96928cec811d65f3c7f9eda6b8..a77f8535e3c142aeb88d4f993a10006d316d8ecf 100644 (file)
@@ -82,6 +82,7 @@ struct LineEntry {
     E.FileOffset = Offs;
     E.LineNo = Line;
     E.FilenameID = Filename;
+    E.FileKind = FileKind;
     return E;
   }
 };
@@ -754,6 +755,37 @@ unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc) const {
   return getLineNumber(LocInfo.first, LocInfo.second);
 }
 
+/// getFileCharacteristic - return the file characteristic of the specified
+/// source location, indicating whether this is a normal file, a system 
+/// header, or an "implicit extern C" system header.
+///
+/// This state can be modified with flags on GNU linemarker directives like:
+///   # 4 "foo.h" 3
+/// which changes all source locations in the current file after that to be
+/// considered to be from a system header.
+SrcMgr::CharacteristicKind 
+SourceManager::getFileCharacteristic(SourceLocation Loc) const {
+  assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!");
+  std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+  const SrcMgr::FileInfo &FI = getSLocEntry(LocInfo.first).getFile();
+
+  // If there are no #line directives in this file, just return the whole-file
+  // state.
+  if (!FI.hasLineDirectives())
+    return FI.getFileCharacteristic();
+  
+  assert(LineTable && "Can't have linetable entries without a LineTable!");
+  // See if there is a #line directive before the location.
+  const LineEntry *Entry =
+    LineTable->FindNearestLineEntry(LocInfo.first.ID, LocInfo.second);
+  
+  // If this is before the first line marker, use the file characteristic.
+  if (!Entry)
+    return FI.getFileCharacteristic();
+
+  return Entry->FileKind;
+}
+
 
 /// getPresumedLoc - This method returns the "presumed" location of a
 /// SourceLocation specifies.  A "presumed location" can be modified by #line
index 6946ad485454282b2ca356a505e792f372be3f48..0a4b5822392d3d517536721b60e11aef8e853ac6 100644 (file)
 #error ABC  // expected-error {{#error ABC}}
 #error DEF  // expected-error {{#error DEF}}
 
+
+// Verify that linemarker diddling of the system header flag works.
+
+# 192 "glomp.h" // not a system header.
+typedef int x;  // expected-note {{previous definition is here}}
+typedef int x;  // expected-error {{redefinition of 'x'}}
+
+# 192 "glomp.h" 3 // System header.
+typedef int y;  // ok
+typedef int y;  // ok
+
+#line 42 "blonk.h"  // doesn't change system headerness.
+
+typedef int z;  // ok
+typedef int z;  // ok
+
+# 42 "blonk.h"  // DOES change system headerness.
+
+typedef int w;  // expected-note {{previous definition is here}}
+typedef int w;  // expected-error {{redefinition of 'w'}}