[cfe-commits] r127919 - /cfe/trunk/tools/libclang/CIndex.cpp

Ted Kremenek kremenek at apple.com
Fri Mar 18 15:51:30 PDT 2011


Author: kremenek
Date: Fri Mar 18 17:51:30 2011
New Revision: 127919

URL: http://llvm.org/viewvc/llvm-project?rev=127919&view=rev
Log:
Run all functional logic of clang_annotateTokens() within a CrashRecoveryContext.  Fixes <rdar://problem/9121698>.

Modified:
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=127919&r1=127918&r2=127919&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Mar 18 17:51:30 2011
@@ -4566,43 +4566,36 @@
   return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
 }
 
-// This gets run a separate thread to avoid stack blowout.
-static void runAnnotateTokensWorker(void *UserData) {
-  ((AnnotateTokensWorker*)UserData)->AnnotateTokens();
+namespace {
+  struct clang_annotateTokens_Data {
+    CXTranslationUnit TU;
+    ASTUnit *CXXUnit;
+    CXToken *Tokens;
+    unsigned NumTokens;
+    CXCursor *Cursors;
+  };
 }
 
-extern "C" {
-
-void clang_annotateTokens(CXTranslationUnit TU,
-                          CXToken *Tokens, unsigned NumTokens,
-                          CXCursor *Cursors) {
-
-  if (NumTokens == 0 || !Tokens || !Cursors)
-    return;
-
-  // Any token we don't specifically annotate will have a NULL cursor.
-  CXCursor C = clang_getNullCursor();
-  for (unsigned I = 0; I != NumTokens; ++I)
-    Cursors[I] = C;
-
-  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
-  if (!CXXUnit)
-    return;
-
-  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+// This gets run a separate thread to avoid stack blowout.
+static void clang_annotateTokensImpl(void *UserData) {
+  CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
+  ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
+  CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
+  const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
+  CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
 
   // Determine the region of interest, which contains all of the tokens.
   SourceRange RegionOfInterest;
-  RegionOfInterest.setBegin(cxloc::translateSourceLocation(
-                                        clang_getTokenLocation(TU, Tokens[0])));
-  RegionOfInterest.setEnd(cxloc::translateSourceLocation(
-                                clang_getTokenLocation(TU, 
-                                                       Tokens[NumTokens - 1])));
+  RegionOfInterest.setBegin(
+    cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
+  RegionOfInterest.setEnd(
+    cxloc::translateSourceLocation(clang_getTokenLocation(TU,
+                                                         Tokens[NumTokens-1])));
 
   // A mapping from the source locations found when re-lexing or traversing the
   // region of interest to the corresponding cursors.
   AnnotateTokensData Annotated;
-
+  
   // Relex the tokens within the source range to look for preprocessing
   // directives.
   SourceManager &SourceMgr = CXXUnit->getSourceManager();
@@ -4610,7 +4603,7 @@
     = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
   std::pair<FileID, unsigned> EndLocInfo
     = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
-
+  
   llvm::StringRef Buffer;
   bool Invalid = false;
   if (BeginLocInfo.first == EndLocInfo.first &&
@@ -4621,13 +4614,13 @@
               Buffer.begin(), Buffer.data() + BeginLocInfo.second,
               Buffer.end());
     Lex.SetCommentRetentionState(true);
-
+    
     // Lex tokens in raw mode until we hit the end of the range, to avoid
     // entering #includes or expanding macros.
     while (true) {
       Token Tok;
       Lex.LexFromRawLexer(Tok);
-
+      
     reprocess:
       if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
         // We have found a preprocessing directive. Gobble it up so that we
@@ -4637,49 +4630,44 @@
         //
         // FIXME: Some simple tests here could identify macro definitions and
         // #undefs, to provide specific cursor kinds for those.
-        std::vector<SourceLocation> Locations;
+        llvm::SmallVector<SourceLocation, 32> Locations;
         do {
           Locations.push_back(Tok.getLocation());
           Lex.LexFromRawLexer(Tok);
         } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
-
+        
         using namespace cxcursor;
         CXCursor Cursor
-          = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
-                                                         Locations.back()),
+        = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
+                                                       Locations.back()),
                                            TU);
         for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
           Annotated[Locations[I].getRawEncoding()] = Cursor;
         }
-
+        
         if (Tok.isAtStartOfLine())
           goto reprocess;
-
+        
         continue;
       }
-
+      
       if (Tok.is(tok::eof))
         break;
     }
   }
-
+  
   // Annotate all of the source locations in the region of interest that map to
   // a specific cursor.
   AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
                          TU, RegionOfInterest);
-
-  // Run the worker within a CrashRecoveryContext.
+  
   // FIXME: We use a ridiculous stack size here because the data-recursion
   // algorithm uses a large stack frame than the non-data recursive version,
   // and AnnotationTokensWorker currently transforms the data-recursion
   // algorithm back into a traditional recursion by explicitly calling
   // VisitChildren().  We will need to remove this explicit recursive call.
-  llvm::CrashRecoveryContext CRC;
-  if (!RunSafely(CRC, runAnnotateTokensWorker, &W,
-                 GetSafetyThreadStackSize() * 2)) {
-    fprintf(stderr, "libclang: crash detected while annotating tokens\n");
-  }
-  
+  W.AnnotateTokens();
+
   // If we ran into any entities that involve context-sensitive keywords,
   // take another pass through the tokens to mark them as such.
   if (W.hasContextSensitiveKeywords()) {
@@ -4690,19 +4678,19 @@
       if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
         if (ObjCPropertyDecl *Property
-              = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
+            = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
           if (Property->getPropertyAttributesAsWritten() != 0 &&
               llvm::StringSwitch<bool>(II->getName())
-                .Case("readonly", true)
-                .Case("assign", true)
-                .Case("readwrite", true)
-                .Case("retain", true)
-                .Case("copy", true)
-                .Case("nonatomic", true)
-                .Case("atomic", true)
-                .Case("getter", true)
-                .Case("setter", true)
-                .Default(false))
+              .Case("readonly", true)
+              .Case("assign", true)
+              .Case("readwrite", true)
+              .Case("retain", true)
+              .Case("copy", true)
+              .Case("nonatomic", true)
+              .Case("atomic", true)
+              .Case("getter", true)
+              .Case("setter", true)
+              .Default(false))
             Tokens[I].int_data[0] = CXToken_Keyword;
         }
         continue;
@@ -4712,13 +4700,13 @@
           Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
         if (llvm::StringSwitch<bool>(II->getName())
-              .Case("in", true)
-              .Case("out", true)
-              .Case("inout", true)
-              .Case("oneway", true)
-              .Case("bycopy", true)
-              .Case("byref", true)
-              .Default(false))
+            .Case("in", true)
+            .Case("out", true)
+            .Case("inout", true)
+            .Case("oneway", true)
+            .Case("bycopy", true)
+            .Case("byref", true)
+            .Default(false))
           Tokens[I].int_data[0] = CXToken_Keyword;
         continue;
       }
@@ -4726,14 +4714,14 @@
       if (Cursors[I].kind == CXCursor_CXXMethod) {
         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
         if (CXXMethodDecl *Method
-                 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
+            = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
           if ((Method->hasAttr<FinalAttr>() || 
                Method->hasAttr<OverrideAttr>()) &&
               Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
               llvm::StringSwitch<bool>(II->getName())
-                .Case("final", true)
-                .Case("override", true)
-                .Default(false))
+              .Case("final", true)
+              .Case("override", true)
+              .Default(false))
             Tokens[I].int_data[0] = CXToken_Keyword;
         }
         continue;
@@ -4753,18 +4741,47 @@
                 Record->getIdentifier() != II)
               Tokens[I].int_data[0] = CXToken_Keyword;
           } else if (ClassTemplateDecl *ClassTemplate
-                       = dyn_cast_or_null<ClassTemplateDecl>(D)) {
+                     = dyn_cast_or_null<ClassTemplateDecl>(D)) {
             CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
             if ((Record->hasAttr<FinalAttr>()) &&
                 Record->getIdentifier() != II)
-              Tokens[I].int_data[0] = CXToken_Keyword;            
+              Tokens[I].int_data[0] = CXToken_Keyword;
           }
         }
-        continue;        
+        continue;
       }
     }
   }
 }
+
+extern "C" {
+
+void clang_annotateTokens(CXTranslationUnit TU,
+                          CXToken *Tokens, unsigned NumTokens,
+                          CXCursor *Cursors) {
+
+  if (NumTokens == 0 || !Tokens || !Cursors)
+    return;
+
+  // Any token we don't specifically annotate will have a NULL cursor.
+  CXCursor C = clang_getNullCursor();
+  for (unsigned I = 0; I != NumTokens; ++I)
+    Cursors[I] = C;
+
+  ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+  if (!CXXUnit)
+    return;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  
+  clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
+  llvm::CrashRecoveryContext CRC;
+  if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
+                 GetSafetyThreadStackSize() * 2)) {
+    fprintf(stderr, "libclang: crash detected while annotating tokens\n");
+  }
+}
+
 } // end: extern "C"
 
 //===----------------------------------------------------------------------===//





More information about the cfe-commits mailing list