]> granicus.if.org Git - clang/commitdiff
When building a PCH file, don't perform end-of-translation-unit
authorDouglas Gregor <dgregor@apple.com>
Tue, 14 Apr 2009 16:27:31 +0000 (16:27 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 14 Apr 2009 16:27:31 +0000 (16:27 +0000)
wrap-up (e.g., turning tentative definitions into definitions). Also,
very that, when we actually use the PCH file, we get the ride code
generation for tentative definitions and definitions that show up in
the PCH file.

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

include/clang/Sema/ParseAST.h
lib/Sema/ParseAST.cpp
lib/Sema/Sema.cpp
lib/Sema/Sema.h
test/PCH/external-defs.c
test/PCH/external-defs.h
tools/clang-cc/clang-cc.cpp

index 882460029d9f2831f35bd29d8431903168e6bd3c..bdce5e95effb5e1a5be174b5bfc1fcbc9170f718 100644 (file)
@@ -19,12 +19,18 @@ namespace clang {
   class ASTConsumer;
   class ASTContext;
 
-  /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
-  /// the file is parsed.    This inserts the parsed decls into the translation unit
-  /// held by Ctx.
+  /// \brief Parse the entire file specified, notifying the ASTConsumer as
+  /// the file is parsed.
   ///
+  /// This operation inserts the parsed decls into the translation
+  /// unit held by Ctx.
+  ///
+  /// \param CompleteTranslationUnit When true, the parsed file is
+  /// considered to be a complete translation unit, and any
+  /// end-of-translation-unit wrapup will be performed.
   void ParseAST(Preprocessor &pp, ASTConsumer *C, 
-                ASTContext &Ctx, bool PrintStats = false);
+                ASTContext &Ctx, bool PrintStats = false,
+                bool CompleteTranslationUnit = true);
 
 }  // end namespace clang
 
index bb5acb0ee8dabe012bea4bff7ba2adcf16b9d3c4..d237f7539e4d5dcda3cbb74df1c4b50fbb618b4d 100644 (file)
@@ -29,14 +29,15 @@ using namespace clang;
 /// held by Ctx.
 ///
 void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
-                     ASTContext &Ctx, bool PrintStats) {
+                     ASTContext &Ctx, bool PrintStats,
+                     bool CompleteTranslationUnit) {
   // Collect global stats on Decls/Stmts (until we have a module streamer).
   if (PrintStats) {
     Decl::CollectingStats(true);
     Stmt::CollectingStats(true);
   }
 
-  Sema S(PP, Ctx, *Consumer);
+  Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit);
   Parser P(PP, S);
   PP.EnterMainSourceFile();
     
index f11ce2043a8ab6ceb6a78c2ccdb74fc9c6857131..403e8f60f56175dc202ff37a78c9433620b7bbf8 100644 (file)
@@ -151,12 +151,14 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
   Context.setObjCIdType(IdTypedef);
 }
 
-Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
+Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
+           bool CompleteTranslationUnit)
   : LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()),
     SourceMgr(PP.getSourceManager()), CurContext(0), PreDeclaratorDC(0),
     CurBlock(0), PackContext(0), IdResolver(pp.getLangOptions()),
-    GlobalNewDeleteDeclared(false) {
+    GlobalNewDeleteDeclared(false), 
+    CompleteTranslationUnit(CompleteTranslationUnit) {
   
   // Get IdentifierInfo objects for known functions for which we
   // do extra checking.  
@@ -216,6 +218,9 @@ void Sema::DeleteStmt(StmtTy *S) {
 /// translation unit when EOF is reached and all but the top-level scope is
 /// popped.
 void Sema::ActOnEndOfTranslationUnit() {
+  if (!CompleteTranslationUnit)
+    return;
+
   // C99 6.9.2p2:
   //   A declaration of an identifier for an object that has file
   //   scope without an initializer, and without a storage-class
index f48e75afb353cf72f9ec9c9bc24d7941d98df2d5..d64228794bdf7d3efb1fc0e651c2819c19fcb9c2 100644 (file)
@@ -214,7 +214,18 @@ public:
   /// A flag to remember whether the implicit forms of operator new and delete
   /// have been declared.
   bool GlobalNewDeleteDeclared;
-  
+
+  /// \brief Whether the code handled by Sema should be considered a
+  /// complete translation unit or not.
+  ///
+  /// When true (which is generally the case), Sema will perform
+  /// end-of-translation-unit semantic tasks (such as creating
+  /// initializers for tentative definitions in C) once parsing has
+  /// completed. This flag will be false when building PCH files,
+  /// since a PCH file is by definition not a complete translation
+  /// unit.
+  bool CompleteTranslationUnit;
+
   /// ObjCMethodList - a linked list of methods with different signatures.
   struct ObjCMethodList {
     ObjCMethodDecl *Method;
@@ -239,7 +250,8 @@ public:
   /// Private Helper predicate to check for 'self'.
   bool isSelfExpr(Expr *RExpr);
 public:
-  Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer);
+  Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
+       bool CompleteTranslationUnit = true);
   ~Sema() {
     if (PackContext) FreePackedContext();
   }
index 7be6c73bc7573b741b1720d0727ff2c20f46e4d1..fd14c4fa8b3505314fa14dbd756518105051644d 100644 (file)
@@ -2,7 +2,20 @@
 // RUN: clang-cc -triple x86_64-apple-darwin9 -emit-pch -o %t.pch %S/external-defs.h &&
 // RUN: clang-cc -triple x86_64-apple-darwin9 -include-pch %t.pch -emit-llvm -o %t %s &&
 
-// RUN: grep "@x = common global i32 0, align 4" %t | count 1 &&
+// RUN: grep "@x = common global i32 0" %t | count 1 &&
 // FIXME below: should be i32 17, but we don't serialize y's value yet
-// RUN: grep "@y = common global i32 0, align 4"  %t | count 1 &&
-// RUN: grep "@z" %t | count 0
+// RUN: grep "@y = common global i32 0"  %t | count 1 &&
+// RUN: grep "@z" %t | count 0 &&
+
+// RUN: grep "@x2 = global i32 19" %t | count 1 &&
+int x2 = 19;
+
+// RUN: grep "@incomplete_array = common global .*1 x i32" %t | count 1 &&
+// RUN: grep "@incomplete_array2 = common global .*17 x i32" %t | count 1 &&
+int incomplete_array2[17];
+// RUN: grep "@incomplete_array3 = common global .*1 x i32" %t | count 1
+int incomplete_array3[];
+
+struct S {
+  int x, y;
+};
index 29345e9c6979f13489fd695636f0ade657913759..4ac9077d12137ec2462fbeee41a41380715d5b0e 100644 (file)
@@ -1,10 +1,17 @@
 // Helper for external-defs.c test
 
-// Tentative definition
+// Tentative definitions
 int x;
+int x2;
 
 // FIXME: check this, once we actually serialize it
 int y = 17;
 
 // Should not show up
 static int z;
+
+int incomplete_array[];
+int incomplete_array2[];
+
+// FIXME: CodeGen problems prevents this from working (<rdar://problem/6762287>)
+// struct S s;
index 91b87f2b05731ff2ad5063d7673fd2117503e6e7..33606494757089545abea67a77ad598755abc375 100644 (file)
@@ -1912,6 +1912,7 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
   llvm::OwningPtr<ASTConsumer> Consumer;
   bool ClearSourceMgr = false;
   FixItRewriter *FixItRewrite = 0;
+  bool CompleteTranslationUnit = true;
 
   switch (PA) {
   default:
@@ -1925,6 +1926,8 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
       return;
     }
 
+    if (ProgAction == GeneratePCH)
+      CompleteTranslationUnit = false;
     break;
       
   case DumpRawTokens: {
@@ -2098,7 +2101,8 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
         return;
     }
 
-    ParseAST(PP, Consumer.get(), *ContextOwner.get(), Stats);
+    ParseAST(PP, Consumer.get(), *ContextOwner.get(), Stats, 
+             CompleteTranslationUnit);
     
     if (FixItRewrite)
       FixItRewrite->WriteFixedFile(InFile, OutputFile);