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
/// 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();
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.
/// 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
/// 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;
/// 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();
}
// 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;
+};
// 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;
llvm::OwningPtr<ASTConsumer> Consumer;
bool ClearSourceMgr = false;
FixItRewriter *FixItRewrite = 0;
+ bool CompleteTranslationUnit = true;
switch (PA) {
default:
return;
}
+ if (ProgAction == GeneratePCH)
+ CompleteTranslationUnit = false;
break;
case DumpRawTokens: {
return;
}
- ParseAST(PP, Consumer.get(), *ContextOwner.get(), Stats);
+ ParseAST(PP, Consumer.get(), *ContextOwner.get(), Stats,
+ CompleteTranslationUnit);
if (FixItRewrite)
FixItRewrite->WriteFixedFile(InFile, OutputFile);