|
@@ -83,46 +83,24 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
|
|
|
// declaration. C++ doesn't have this restriction. We also don't want to
|
|
|
// complain if we have a precompiled header, although technically if the PCH
|
|
|
// is empty we should still emit the (pedantic) diagnostic.
|
|
|
- bool WarnForEmptyTU = !S.getLangOpts().CPlusPlus;
|
|
|
- if (ExternalASTSource *External = S.getASTContext().getExternalSource()) {
|
|
|
- External->StartTranslationUnit(Consumer);
|
|
|
- WarnForEmptyTU = false;
|
|
|
- }
|
|
|
-
|
|
|
- // Clang's predefines contain top-level declarations for things like va_list,
|
|
|
- // making it hard to tell if the /user's/ translation unit has at least one
|
|
|
- // top-level declaration. So we parse cautiously, looking for a declaration
|
|
|
- // that doesn't come from our predefines.
|
|
|
- // Note that ParseTopLevelDecl returns 'true' at EOF.
|
|
|
- SourceManager &SM = S.getSourceManager();
|
|
|
Parser::DeclGroupPtrTy ADecl;
|
|
|
- while (WarnForEmptyTU && !P.ParseTopLevelDecl(ADecl)) {
|
|
|
- if (ADecl) {
|
|
|
- if (!Consumer->HandleTopLevelDecl(ADecl.get()))
|
|
|
- return;
|
|
|
- if (DeclGroupRef::iterator FirstDecl = ADecl.get().begin()) {
|
|
|
- SourceLocation DeclLoc = (*FirstDecl)->getLocation();
|
|
|
- WarnForEmptyTU = SM.isFromPredefines(DeclLoc);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ ExternalASTSource *External = S.getASTContext().getExternalSource();
|
|
|
+ if (External)
|
|
|
+ External->StartTranslationUnit(Consumer);
|
|
|
|
|
|
- // If we ended up seeing EOF before any top-level declarations, emit our
|
|
|
- // diagnostic. Otherwise, parse the rest of the file normally.
|
|
|
- if (WarnForEmptyTU) {
|
|
|
- P.Diag(diag::ext_empty_translation_unit);
|
|
|
+ if (P.ParseTopLevelDecl(ADecl)) {
|
|
|
+ if (!External && !S.getLangOpts().CPlusPlus)
|
|
|
+ P.Diag(diag::ext_empty_translation_unit);
|
|
|
} else {
|
|
|
- while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file.
|
|
|
+ do {
|
|
|
// If we got a null return and something *was* parsed, ignore it. This
|
|
|
// is due to a top-level semicolon, an action override, or a parse error
|
|
|
// skipping something.
|
|
|
- if (ADecl) {
|
|
|
- if (!Consumer->HandleTopLevelDecl(ADecl.get()))
|
|
|
- return;
|
|
|
- }
|
|
|
- };
|
|
|
+ if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
|
|
|
+ return;
|
|
|
+ } while (!P.ParseTopLevelDecl(ADecl));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// Process any TopLevelDecls generated by #pragma weak.
|
|
|
for (SmallVector<Decl*,2>::iterator
|
|
|
I = S.WeakTopLevelDecls().begin(),
|