2008-02-06 08:23:21 +08:00
|
|
|
//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
|
2006-08-17 14:28:25 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-08-17 14:28:25 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2008-02-06 08:23:21 +08:00
|
|
|
// This file implements the clang::ParseAST method.
|
2006-08-17 14:28:25 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-21 02:27:03 +08:00
|
|
|
#include "clang/Parse/ParseAST.h"
|
2012-06-07 01:25:21 +08:00
|
|
|
#include "clang/Parse/ParseDiagnostic.h"
|
2010-08-13 04:07:10 +08:00
|
|
|
#include "clang/Sema/Sema.h"
|
Initial implementation of a code-completion interface in Clang. In
essence, code completion is triggered by a magic "code completion"
token produced by the lexer [*], which the parser recognizes at
certain points in the grammar. The parser then calls into the Action
object with the appropriate CodeCompletionXXX action.
Sema implements the CodeCompletionXXX callbacks by performing minimal
translation, then forwarding them to a CodeCompletionConsumer
subclass, which uses the results of semantic analysis to provide
code-completion results. At present, only a single, "printing" code
completion consumer is available, for regression testing and
debugging. However, the design is meant to permit other
code-completion consumers.
This initial commit contains two code-completion actions: one for
member access, e.g., "x." or "p->", and one for
nested-name-specifiers, e.g., "std::". More code-completion actions
will follow, along with improved gathering of code-completion results
for the various contexts.
[*] In the current -code-completion-dump testing/debugging mode, the
file is truncated at the completion point and EOF is translated into
"code completion".
llvm-svn: 82166
2009-09-18 05:32:03 +08:00
|
|
|
#include "clang/Sema/CodeCompleteConsumer.h"
|
2009-04-20 23:53:59 +08:00
|
|
|
#include "clang/Sema/SemaConsumer.h"
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
#include "clang/Sema/ExternalSemaSource.h"
|
2007-09-16 06:56:56 +08:00
|
|
|
#include "clang/AST/ASTConsumer.h"
|
2010-08-25 15:42:41 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2009-04-14 08:24:19 +08:00
|
|
|
#include "clang/AST/ExternalASTSource.h"
|
2008-08-11 12:54:23 +08:00
|
|
|
#include "clang/AST/Stmt.h"
|
2006-08-17 14:28:25 +08:00
|
|
|
#include "clang/Parse/Parser.h"
|
2011-03-18 11:44:21 +08:00
|
|
|
#include "llvm/ADT/OwningPtr.h"
|
2011-03-18 10:06:53 +08:00
|
|
|
#include "llvm/Support/CrashRecoveryContext.h"
|
2009-08-24 21:25:12 +08:00
|
|
|
#include <cstdio>
|
|
|
|
|
2006-08-17 14:28:25 +08:00
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Public interface to the file
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-09-16 06:56:56 +08:00
|
|
|
/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
|
2009-03-28 12:13:34 +08:00
|
|
|
/// the file is parsed. This inserts the parsed decls into the translation unit
|
|
|
|
/// held by Ctx.
|
2008-10-17 00:54:18 +08:00
|
|
|
///
|
2009-01-28 12:29:29 +08:00
|
|
|
void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
|
2009-04-15 00:27:31 +08:00
|
|
|
ASTContext &Ctx, bool PrintStats,
|
2011-08-26 06:30:56 +08:00
|
|
|
TranslationUnitKind TUKind,
|
2012-04-12 18:11:59 +08:00
|
|
|
CodeCompleteConsumer *CompletionConsumer,
|
|
|
|
bool SkipFunctionBodies) {
|
2011-03-18 11:44:21 +08:00
|
|
|
|
2012-02-05 10:12:40 +08:00
|
|
|
OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer,
|
2011-08-26 06:30:56 +08:00
|
|
|
TUKind,
|
2011-03-18 11:44:21 +08:00
|
|
|
CompletionConsumer));
|
2011-03-18 10:06:53 +08:00
|
|
|
|
|
|
|
// Recover resources if we crash before exiting this method.
|
2012-04-12 18:11:59 +08:00
|
|
|
llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(S.get());
|
2011-03-18 10:06:53 +08:00
|
|
|
|
2012-04-12 18:11:59 +08:00
|
|
|
ParseAST(*S.get(), PrintStats, SkipFunctionBodies);
|
2010-08-13 06:51:45 +08:00
|
|
|
}
|
|
|
|
|
2012-04-12 18:11:59 +08:00
|
|
|
void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
|
2007-09-16 06:56:56 +08:00
|
|
|
// Collect global stats on Decls/Stmts (until we have a module streamer).
|
|
|
|
if (PrintStats) {
|
2012-03-06 05:42:49 +08:00
|
|
|
Decl::EnableStatistics();
|
|
|
|
Stmt::EnableStatistics();
|
2007-09-16 06:56:56 +08:00
|
|
|
}
|
2009-01-28 12:29:29 +08:00
|
|
|
|
2011-07-07 00:21:37 +08:00
|
|
|
// Also turn on collection of stats inside of the Sema object.
|
|
|
|
bool OldCollectStats = PrintStats;
|
|
|
|
std::swap(OldCollectStats, S.CollectStats);
|
|
|
|
|
2010-08-13 06:51:45 +08:00
|
|
|
ASTConsumer *Consumer = &S.getASTConsumer();
|
2010-08-13 05:39:05 +08:00
|
|
|
|
2012-04-12 18:11:59 +08:00
|
|
|
OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S,
|
|
|
|
SkipFunctionBodies));
|
2011-03-22 09:15:17 +08:00
|
|
|
Parser &P = *ParseOP.get();
|
|
|
|
|
|
|
|
PrettyStackTraceParserEntry CrashInfo(P);
|
|
|
|
|
|
|
|
// Recover resources if we crash before exiting this method.
|
|
|
|
llvm::CrashRecoveryContextCleanupRegistrar<Parser>
|
2012-04-12 18:11:59 +08:00
|
|
|
CleanupParser(ParseOP.get());
|
2011-03-22 09:15:17 +08:00
|
|
|
|
2010-08-13 06:51:45 +08:00
|
|
|
S.getPreprocessor().EnterMainSourceFile();
|
2010-08-13 05:39:05 +08:00
|
|
|
P.Initialize();
|
2010-08-13 06:51:45 +08:00
|
|
|
S.Initialize();
|
2012-06-07 01:25:21 +08:00
|
|
|
|
|
|
|
// C11 6.9p1 says translation units must have at least one top-level
|
|
|
|
// 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.
|
2009-03-30 00:50:03 +08:00
|
|
|
Parser::DeclGroupPtrTy ADecl;
|
2012-06-20 02:17:30 +08:00
|
|
|
ExternalASTSource *External = S.getASTContext().getExternalSource();
|
|
|
|
if (External)
|
|
|
|
External->StartTranslationUnit(Consumer);
|
2011-11-18 08:26:59 +08:00
|
|
|
|
2012-06-20 02:17:30 +08:00
|
|
|
if (P.ParseTopLevelDecl(ADecl)) {
|
|
|
|
if (!External && !S.getLangOpts().CPlusPlus)
|
|
|
|
P.Diag(diag::ext_empty_translation_unit);
|
2012-06-07 01:25:21 +08:00
|
|
|
} else {
|
2012-06-20 02:17:30 +08:00
|
|
|
do {
|
2012-06-07 01:25:21 +08:00
|
|
|
// 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.
|
2012-06-20 02:17:30 +08:00
|
|
|
if (ADecl && !Consumer->HandleTopLevelDecl(ADecl.get()))
|
|
|
|
return;
|
|
|
|
} while (!P.ParseTopLevelDecl(ADecl));
|
2012-06-07 01:25:21 +08:00
|
|
|
}
|
2012-06-20 02:17:30 +08:00
|
|
|
|
2009-12-02 05:57:20 +08:00
|
|
|
// Process any TopLevelDecls generated by #pragma weak.
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVector<Decl*,2>::iterator
|
2010-08-13 06:51:45 +08:00
|
|
|
I = S.WeakTopLevelDecls().begin(),
|
|
|
|
E = S.WeakTopLevelDecls().end(); I != E; ++I)
|
2009-07-31 10:52:19 +08:00
|
|
|
Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
|
2010-08-13 06:51:45 +08:00
|
|
|
|
|
|
|
Consumer->HandleTranslationUnit(S.getASTContext());
|
2011-07-07 00:21:37 +08:00
|
|
|
|
|
|
|
std::swap(OldCollectStats, S.CollectStats);
|
2007-09-16 06:56:56 +08:00
|
|
|
if (PrintStats) {
|
2011-07-04 13:32:14 +08:00
|
|
|
llvm::errs() << "\nSTATISTICS:\n";
|
2008-02-06 08:15:02 +08:00
|
|
|
P.getActions().PrintStats();
|
2010-08-13 06:51:45 +08:00
|
|
|
S.getASTContext().PrintStats();
|
2007-09-16 06:56:56 +08:00
|
|
|
Decl::PrintStats();
|
|
|
|
Stmt::PrintStats();
|
2007-11-03 14:24:16 +08:00
|
|
|
Consumer->PrintStats();
|
2007-09-16 06:56:56 +08:00
|
|
|
}
|
|
|
|
}
|