[cfe-commits] r84267 - in /cfe/trunk: include/clang-c/Index.h include/clang/AST/DeclBase.h include/clang/Frontend/ASTUnit.h lib/Frontend/ASTUnit.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp test/Index/c-index-pch.c tools/CIndex/CIndex.cpp tools/CIndex/CIndex.exports tools/c-index-test/c-index-test.c
Douglas Gregor
dgregor at apple.com
Fri Oct 16 13:01:18 PDT 2009
Author: dgregor
Date: Fri Oct 16 15:01:17 2009
New Revision: 84267
URL: http://llvm.org/viewvc/llvm-project?rev=84267&view=rev
Log:
Keep track of whether declararions were loaded from a precompiled
header or not via a new "PCHLevel" field in Decl. We currently use
this information to help CIndex filter out declarations that came from
a precompiled header (rather than from an AST file). Further down the
road, it can be used to help implement multi-level precompiled
headers.
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/Frontend/ASTUnit.h
cfe/trunk/lib/Frontend/ASTUnit.cpp
cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
cfe/trunk/test/Index/c-index-pch.c
cfe/trunk/tools/CIndex/CIndex.cpp
cfe/trunk/tools/CIndex/CIndex.exports
cfe/trunk/tools/c-index-test/c-index-test.c
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Fri Oct 16 15:01:17 2009
@@ -117,6 +117,17 @@
);
void clang_disposeTranslationUnit(CXTranslationUnit);
+/**
+ * \brief Indicate to Clang that it should only enumerate "local" declarations
+ * when loading any new translation units.
+ *
+ * A "local" declaration is one that belongs in the translation unit itself and
+ * not in a precompiled header that was used by the translation unit.
+ *
+ * FIXME: Remove this hook.
+ */
+void clang_wantOnlyLocalDeclarations(CXIndex);
+
/*
Usage: clang_loadTranslationUnit(). Will load the toplevel declarations
within a translation unit, issuing a 'callback' for each one.
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Oct 16 15:01:17 2009
@@ -166,6 +166,15 @@
bool Used : 1;
protected:
+ /// Access - Used by C++ decls for the access specifier.
+ // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+ unsigned Access : 2;
+ friend class CXXClassMemberWrapper;
+
+ // PCHLevel - the "level" of precompiled header/AST file from which this
+ // declaration was built.
+ unsigned PCHLevel : 2;
+
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 16;
@@ -177,16 +186,13 @@
#endif
protected:
- /// Access - Used by C++ decls for the access specifier.
- // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
- unsigned Access : 2;
- friend class CXXClassMemberWrapper;
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)), Access(AS_none) {
+ Access(AS_none), PCHLevel(0),
+ IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
if (Decl::CollectingStats()) addDeclKind(DK);
}
@@ -274,6 +280,26 @@
bool isUsed() const { return Used; }
void setUsed(bool U = true) { Used = U; }
+ /// \brief Retrieve the level of precompiled header from which this
+ /// declaration was generated.
+ ///
+ /// The PCH level of a declaration describes where the declaration originated
+ /// from. A PCH level of 0 indicates that the declaration was not from a
+ /// precompiled header. A PCH level of 1 indicates that the declaration was
+ /// from a top-level precompiled header; 2 indicates that the declaration
+ /// comes from a precompiled header on which the top-level precompiled header
+ /// depends, and so on.
+ unsigned getPCHLevel() const { return PCHLevel; }
+
+ /// \brief The maximum PCH level that any declaration may have.
+ static const unsigned MaxPCHLevel = 3;
+
+ /// \brief Set the PCH level of this declaration.
+ void setPCHLevel(unsigned Level) {
+ assert(Level < MaxPCHLevel && "PCH level exceeds the maximum");
+ PCHLevel = Level;
+ }
+
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Fri Oct 16 15:01:17 2009
@@ -40,6 +40,11 @@
llvm::OwningPtr<ASTContext> Ctx;
bool tempFile;
+ // OnlyLocalDecls - when true, walking this AST should only visit declarations
+ // that come from the AST itself, not from included precompiled headers.
+ // FIXME: This is temporary; eventually, CIndex will always do this.
+ bool OnlyLocalDecls;
+
ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
ASTUnit(Diagnostic &_Diag);
@@ -65,6 +70,8 @@
void unlinkTemporaryFile() { tempFile = true; }
+ bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+
/// \brief Create a ASTUnit from a PCH file.
///
/// \param Filename - The PCH file to load.
@@ -80,7 +87,8 @@
static ASTUnit *LoadFromPCHFile(const std::string &Filename,
Diagnostic &Diags,
FileManager &FileMgr,
- std::string *ErrMsg = 0);
+ std::string *ErrMsg = 0,
+ bool OnlyLocalDecls = false);
};
} // namespace clang
Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Fri Oct 16 15:01:17 2009
@@ -94,9 +94,10 @@
ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
Diagnostic &Diags,
FileManager &FileMgr,
- std::string *ErrMsg) {
+ std::string *ErrMsg,
+ bool OnlyLocalDecls) {
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(Diags));
-
+ AST->OnlyLocalDecls = OnlyLocalDecls;
AST->HeaderInfo.reset(new HeaderSearch(FileMgr));
// Gather Info for preprocessor construction later on.
Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Fri Oct 16 15:01:17 2009
@@ -86,6 +86,7 @@
D->setImplicit(Record[Idx++]);
D->setUsed(Record[Idx++]);
D->setAccess((AccessSpecifier)Record[Idx++]);
+ D->setPCHLevel(Record[Idx++] + 1);
}
void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Fri Oct 16 15:01:17 2009
@@ -88,6 +88,7 @@
Record.push_back(D->isImplicit());
Record.push_back(D->isUsed());
Record.push_back(D->getAccess());
+ Record.push_back(D->getPCHLevel());
}
void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
@@ -448,6 +449,7 @@
!D->isImplicit() &&
!D->isUsed() &&
D->getAccess() == AS_none &&
+ D->getPCHLevel() == 0 &&
D->getStorageClass() == 0 &&
!D->hasCXXDirectInitializer() && // Can params have this ever?
D->getObjCDeclQualifier() == 0)
@@ -523,6 +525,7 @@
Abv->Add(BitCodeAbbrevOp(0)); // isImplicit
Abv->Add(BitCodeAbbrevOp(0)); // isUsed
Abv->Add(BitCodeAbbrevOp(AS_none)); // C++ AccessSpecifier
+ Abv->Add(BitCodeAbbrevOp(0)); // PCH level
// NamedDecl
Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier
Modified: cfe/trunk/test/Index/c-index-pch.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/c-index-pch.c?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/test/Index/c-index-pch.c (original)
+++ cfe/trunk/test/Index/c-index-pch.c Fri Oct 16 15:01:17 2009
@@ -1,7 +1,14 @@
// RUN: clang-cc -emit-pch -x c -o %t.pch %S/c-index-pch.h &&
// RUN: clang-cc -include-pch %t.pch -x c -emit-pch -o %t.ast %s &&
-// RUN: c-index-test %t.ast all | FileCheck -check-prefix=ALL %s
-// CHECK-ALL: FunctionDecl=foo
-// CHECK-ALL: VarDecl=bar
-// CHECK-ALL: FunctionDecl=wibble
+// RUN: c-index-test %t.ast all | FileCheck -check-prefix=ALL %s &&
+// RUN: c-index-test %t.ast local | FileCheck -check-prefix=LOCAL %s
+// ALL: FunctionDecl=foo
+// ALL: VarDecl=bar
+// ALL: FunctionDecl=wibble
+// ALL: FunctionDecl=wonka
+// LOCAL-NOT: FunctionDecl=foo
+// LOCAL-NOT: VarDecl=bar
+// LOCAL: FunctionDecl=wibble
+// LOCAL: FunctionDecl=wonka
void wibble(int i);
+void wonka(float);
Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Fri Oct 16 15:01:17 2009
@@ -88,14 +88,24 @@
CXTranslationUnitIterator Callback;
CXClientData CData;
+ // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
+ // to the visitor. Declarations with a PCH level greater than this value will
+ // be suppressed.
+ unsigned MaxPCHLevel;
+
void Call(enum CXCursorKind CK, NamedDecl *ND) {
+ // Filter any declarations that have a PCH level greater than what we allow.
+ if (ND->getPCHLevel() > MaxPCHLevel)
+ return;
+
CXCursor C = { CK, ND, 0 };
Callback(TUnit, C, CData);
}
public:
TUVisitor(CXTranslationUnit CTU,
- CXTranslationUnitIterator cback, CXClientData D) :
- TUnit(CTU), Callback(cback), CData(D) {}
+ CXTranslationUnitIterator cback, CXClientData D,
+ unsigned MaxPCHLevel) :
+ TUnit(CTU), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
void VisitTranslationUnitDecl(TranslationUnitDecl *D) {
VisitDeclContext(dyn_cast<DeclContext>(D));
@@ -154,16 +164,27 @@
CXDeclIterator Callback;
CXClientData CData;
+ // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
+ // to the visitor. Declarations with a PCH level greater than this value will
+ // be suppressed.
+ unsigned MaxPCHLevel;
+
void Call(enum CXCursorKind CK, NamedDecl *ND) {
// Disable the callback when the context is equal to the visiting decl.
if (CDecl == ND && !clang_isReference(CK))
return;
+
+ // Filter any declarations that have a PCH level greater than what we allow.
+ if (ND->getPCHLevel() > MaxPCHLevel)
+ return;
+
CXCursor C = { CK, ND, 0 };
Callback(CDecl, C, CData);
}
public:
- CDeclVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) :
- CDecl(C), Callback(cback), CData(D) {}
+ CDeclVisitor(CXDecl C, CXDeclIterator cback, CXClientData D,
+ unsigned MaxPCHLevel) :
+ CDecl(C), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
// Issue callbacks for the containing class.
@@ -242,6 +263,20 @@
}
};
+class CIndexer : public Indexer {
+public:
+ explicit CIndexer(Program &prog) : Indexer(prog), OnlyLocalDecls(false) { }
+
+ /// \brief Whether we only want to see "local" declarations (that did not
+ /// come from a previous precompiled header). If false, we want to see all
+ /// declarations.
+ bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+ void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; }
+
+private:
+ bool OnlyLocalDecls;
+};
+
}
extern "C" {
@@ -267,13 +302,13 @@
clangPath = ClangPath.c_str();
- return new Indexer(*new Program());
+ return new CIndexer(*new Program());
}
void clang_disposeIndex(CXIndex CIdx)
{
assert(CIdx && "Passed null CXIndex");
- delete static_cast<Indexer *>(CIdx);
+ delete static_cast<CIndexer *>(CIdx);
}
// FIXME: need to pass back error info.
@@ -281,12 +316,13 @@
CXIndex CIdx, const char *ast_filename)
{
assert(CIdx && "Passed null CXIndex");
- Indexer *CXXIdx = static_cast<Indexer *>(CIdx);
+ CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
std::string astName(ast_filename);
std::string ErrMsg;
return ASTUnit::LoadFromPCHFile(astName, CXXIdx->getDiagnostics(),
- CXXIdx->getFileManager(), &ErrMsg);
+ CXXIdx->getFileManager(), &ErrMsg,
+ CXXIdx->getOnlyLocalDecls());
}
CXTranslationUnit clang_createTranslationUnitFromSourceFile(
@@ -338,6 +374,10 @@
delete static_cast<ASTUnit *>(CTUnit);
}
+void clang_wantOnlyLocalDeclarations(CXIndex CIdx) {
+ static_cast<CIndexer *>(CIdx)->setOnlyLocalDecls(true);
+}
+
const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)
{
assert(CTUnit && "Passed null CXTranslationUnit");
@@ -353,7 +393,8 @@
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
ASTContext &Ctx = CXXUnit->getASTContext();
- TUVisitor DVisit(CTUnit, callback, CData);
+ TUVisitor DVisit(CTUnit, callback, CData,
+ CXXUnit->getOnlyLocalDecls()? 1 : Decl::MaxPCHLevel);
DVisit.Visit(Ctx.getTranslationUnitDecl());
}
@@ -363,7 +404,8 @@
{
assert(Dcl && "Passed null CXDecl");
- CDeclVisitor DVisit(Dcl, callback, CData);
+ CDeclVisitor DVisit(Dcl, callback, CData,
+ static_cast<Decl *>(Dcl)->getPCHLevel());
DVisit.Visit(static_cast<Decl *>(Dcl));
}
Modified: cfe/trunk/tools/CIndex/CIndex.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.exports?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.exports (original)
+++ cfe/trunk/tools/CIndex/CIndex.exports Fri Oct 16 15:01:17 2009
@@ -28,3 +28,4 @@
_clang_getCursorKindSpelling
_clang_getDefinitionSpellingAndExtent
_clang_getTranslationUnitSpelling
+_clang_wantOnlyLocalDeclarations
Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=84267&r1=84266&r2=84267&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Fri Oct 16 15:01:17 2009
@@ -86,10 +86,16 @@
}
{
CXIndex Idx = clang_createIndex();
+ if (!strcmp(argv[2], "local"))
+ clang_wantOnlyLocalDeclarations(Idx);
CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]);
+ if (!TU) {
+ fprintf(stderr, "Unable to load translation unit!\n");
+ return 1;
+ }
enum CXCursorKind K = CXCursor_NotImplemented;
- if (!strcmp(argv[2], "all")) {
+ if (!strcmp(argv[2], "all") || !strcmp(argv[2], "local")) {
clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
clang_disposeTranslationUnit(TU);
return 1;
More information about the cfe-commits
mailing list