зеркало из https://github.com/microsoft/clang-1.git
Comment AST: add DeclInfo to store information about the declaration. Sema was
already extracting most of this, but discarding at the end of semantic analysis. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161140 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2ff84b514e
Коммит
1ca7ecc885
|
@ -19,6 +19,10 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace clang {
|
||||
class Decl;
|
||||
class ParmVarDecl;
|
||||
class TemplateParameterList;
|
||||
|
||||
namespace comments {
|
||||
|
||||
/// Any part of the comment.
|
||||
|
@ -906,14 +910,61 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// Information about the declaration, useful to clients of FullComment.
|
||||
struct DeclInfo {
|
||||
/// Declaration the comment is attached to. Should not be NULL.
|
||||
const Decl *ThisDecl;
|
||||
|
||||
/// Parameters that can be referenced by \\param if \c ThisDecl is something
|
||||
/// that we consider a "function".
|
||||
ArrayRef<const ParmVarDecl *> ParamVars;
|
||||
|
||||
/// Template parameters that can be referenced by \\tparam if \c ThisDecl is
|
||||
/// a template.
|
||||
const TemplateParameterList *TemplateParameters;
|
||||
|
||||
/// If false, only \c ThisDecl is valid.
|
||||
unsigned IsFilled : 1;
|
||||
|
||||
/// Is \c ThisDecl something that we consider a "function".
|
||||
unsigned IsFunctionDecl : 1;
|
||||
|
||||
/// Is \c ThisDecl something that we consider a "class".
|
||||
unsigned IsClassDecl : 1;
|
||||
|
||||
/// Is \c ThisDecl a template declaration.
|
||||
unsigned IsTemplateDecl : 1;
|
||||
|
||||
/// Is \c ThisDecl a template specialization.
|
||||
unsigned IsTemplateSpecialization : 1;
|
||||
|
||||
/// Is \c ThisDecl a template partial specialization.
|
||||
/// Never true if \c IsFunctionDecl is true.
|
||||
unsigned IsTemplatePartialSpecialization : 1;
|
||||
|
||||
/// Is \c ThisDecl a non-static member function of C++ class or
|
||||
/// instance method of ObjC class.
|
||||
/// Can be true only if \c IsFunctionDecl is true.
|
||||
unsigned IsInstanceMethod : 1;
|
||||
|
||||
/// Is \c ThisDecl a static member function of C++ class or
|
||||
/// class method of ObjC class.
|
||||
/// Can be true only if \c IsFunctionDecl is true.
|
||||
unsigned IsClassMethod : 1;
|
||||
|
||||
void fill();
|
||||
};
|
||||
|
||||
/// A full comment attached to a declaration, contains block content.
|
||||
class FullComment : public Comment {
|
||||
llvm::ArrayRef<BlockContentComment *> Blocks;
|
||||
|
||||
DeclInfo *ThisDeclInfo;
|
||||
|
||||
public:
|
||||
FullComment(llvm::ArrayRef<BlockContentComment *> Blocks) :
|
||||
FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
|
||||
Comment(FullCommentKind, SourceLocation(), SourceLocation()),
|
||||
Blocks(Blocks) {
|
||||
Blocks(Blocks), ThisDeclInfo(D) {
|
||||
if (Blocks.empty())
|
||||
return;
|
||||
|
||||
|
@ -935,6 +986,16 @@ public:
|
|||
child_iterator child_end() const {
|
||||
return reinterpret_cast<child_iterator>(Blocks.end());
|
||||
}
|
||||
|
||||
const Decl *getDecl() const LLVM_READONLY {
|
||||
return ThisDeclInfo->ThisDecl;
|
||||
}
|
||||
|
||||
const DeclInfo *getDeclInfo() const LLVM_READONLY {
|
||||
if (!ThisDeclInfo->IsFilled)
|
||||
ThisDeclInfo->fill();
|
||||
return ThisDeclInfo;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace comments
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
|
||||
namespace clang {
|
||||
class Decl;
|
||||
class FunctionDecl;
|
||||
class ParmVarDecl;
|
||||
class TemplateParameterList;
|
||||
class SourceMgr;
|
||||
|
||||
namespace comments {
|
||||
|
@ -43,45 +40,22 @@ class Sema {
|
|||
|
||||
DiagnosticsEngine &Diags;
|
||||
|
||||
/// Declaration this comment is attached to.
|
||||
const Decl *ThisDecl;
|
||||
|
||||
/// Parameters that can be referenced by \\param if \c ThisDecl is something
|
||||
/// that we consider a "function".
|
||||
/// Contains a valid value if \c IsThisDeclInspected is true.
|
||||
ArrayRef<const ParmVarDecl *> ParamVars;
|
||||
/// Information about the declaration this comment is attached to.
|
||||
DeclInfo *ThisDeclInfo;
|
||||
|
||||
/// Comment AST nodes that correspond to \c ParamVars for which we have
|
||||
/// found a \\param command or NULL if no documentation was found so far.
|
||||
///
|
||||
/// Has correct size and contains valid values if \c IsThisDeclInspected is
|
||||
/// Has correct size and contains valid values if \c DeclInfo->IsFilled is
|
||||
/// true.
|
||||
llvm::SmallVector<ParamCommandComment *, 8> ParamVarDocs;
|
||||
|
||||
/// Template parameters that can be referenced by \\tparam if \c ThisDecl is
|
||||
/// a template.
|
||||
///
|
||||
/// Contains a valid value if \c IsThisDeclInspected is true.
|
||||
const TemplateParameterList *TemplateParameters;
|
||||
|
||||
/// Comment AST nodes that correspond to parameter names in
|
||||
/// \c TemplateParameters.
|
||||
///
|
||||
/// Contains a valid value if \c IsThisDeclInspected is true.
|
||||
/// Contains a valid value if \c DeclInfo->IsFilled is true.
|
||||
llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
|
||||
|
||||
/// True if we extracted all important information from \c ThisDecl into
|
||||
/// \c Sema members.
|
||||
unsigned IsThisDeclInspected : 1;
|
||||
|
||||
/// Is \c ThisDecl something that we consider a "function".
|
||||
/// Contains a valid value if \c IsThisDeclInspected is true.
|
||||
unsigned IsFunctionDecl : 1;
|
||||
|
||||
/// Is \c ThisDecl a template declaration.
|
||||
/// Contains a valid value if \c IsThisDeclInspected is true.
|
||||
unsigned IsTemplateDecl : 1;
|
||||
|
||||
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
|
||||
return Diags.Report(Loc, DiagID);
|
||||
}
|
||||
|
@ -212,8 +186,8 @@ public:
|
|||
|
||||
ArrayRef<const ParmVarDecl *> getParamVars();
|
||||
|
||||
/// Extract all important semantic information from \c ThisDecl into
|
||||
/// \c Sema members.
|
||||
/// Extract all important semantic information from
|
||||
/// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
|
||||
void inspectThisDecl();
|
||||
|
||||
/// Returns index of a function parameter with a given name.
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/AST/Comment.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
|
@ -134,5 +137,66 @@ const char *ParamCommandComment::getDirectionAsString(PassDirection D) {
|
|||
llvm_unreachable("unknown PassDirection");
|
||||
}
|
||||
|
||||
void DeclInfo::fill() {
|
||||
assert(!IsFilled);
|
||||
|
||||
// Set defaults.
|
||||
IsFunctionDecl = false;
|
||||
IsTemplateDecl = false;
|
||||
IsTemplateSpecialization = false;
|
||||
IsTemplatePartialSpecialization = false;
|
||||
IsInstanceMethod = false;
|
||||
IsClassMethod = false;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>();
|
||||
TemplateParameters = NULL;
|
||||
|
||||
if (!ThisDecl) {
|
||||
// Defaults are OK.
|
||||
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = true;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
|
||||
FD->getNumParams());
|
||||
unsigned NumLists = FD->getNumTemplateParameterLists();
|
||||
if (NumLists != 0) {
|
||||
IsTemplateDecl = true;
|
||||
IsTemplateSpecialization = true;
|
||||
TemplateParameters =
|
||||
FD->getTemplateParameterList(NumLists - 1);
|
||||
}
|
||||
|
||||
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
|
||||
IsInstanceMethod = MD->isInstance();
|
||||
IsClassMethod = !IsInstanceMethod;
|
||||
}
|
||||
} else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = true;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
|
||||
MD->param_size());
|
||||
IsInstanceMethod = MD->isInstanceMethod();
|
||||
IsClassMethod = !IsInstanceMethod;
|
||||
} else if (const FunctionTemplateDecl *FTD =
|
||||
dyn_cast<FunctionTemplateDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = true;
|
||||
IsTemplateDecl = true;
|
||||
const FunctionDecl *FD = FTD->getTemplatedDecl();
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
|
||||
FD->getNumParams());
|
||||
TemplateParameters = FTD->getTemplateParameters();
|
||||
} else if (const ClassTemplateDecl *CTD =
|
||||
dyn_cast<ClassTemplateDecl>(ThisDecl)) {
|
||||
IsTemplateDecl = true;
|
||||
TemplateParameters = CTD->getTemplateParameters();
|
||||
} else if (const ClassTemplatePartialSpecializationDecl *CTPSD =
|
||||
dyn_cast<ClassTemplatePartialSpecializationDecl>(ThisDecl)) {
|
||||
IsTemplateDecl = true;
|
||||
IsTemplatePartialSpecialization = true;
|
||||
TemplateParameters = CTPSD->getTemplateParameters();
|
||||
} else if (isa<ClassTemplateSpecializationDecl>(ThisDecl)) {
|
||||
IsTemplateDecl = true;
|
||||
IsTemplateSpecialization = true;
|
||||
}
|
||||
IsFilled = true;
|
||||
}
|
||||
|
||||
} // end namespace comments
|
||||
} // end namespace clang
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "clang/AST/CommentSema.h"
|
||||
#include "clang/AST/CommentDiagnostic.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
|
@ -20,12 +19,16 @@ namespace comments {
|
|||
|
||||
Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
|
||||
DiagnosticsEngine &Diags) :
|
||||
Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), ThisDecl(NULL),
|
||||
IsThisDeclInspected(false) {
|
||||
Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags),
|
||||
ThisDeclInfo(NULL) {
|
||||
}
|
||||
|
||||
void Sema::setDecl(const Decl *D) {
|
||||
ThisDecl = D;
|
||||
if (!D)
|
||||
return;
|
||||
|
||||
ThisDeclInfo = new (Allocator) DeclInfo;
|
||||
ThisDeclInfo->ThisDecl = D;
|
||||
}
|
||||
|
||||
ParagraphComment *Sema::actOnParagraphComment(
|
||||
|
@ -234,6 +237,8 @@ TParamCommandComment *Sema::actOnTParamCommandParamNameArg(
|
|||
return Command;
|
||||
}
|
||||
|
||||
const TemplateParameterList *TemplateParameters =
|
||||
ThisDeclInfo->TemplateParameters;
|
||||
SmallVector<unsigned, 2> Position;
|
||||
if (resolveTParamReference(Arg, TemplateParameters, &Position)) {
|
||||
Command->setPosition(copyArray(llvm::makeArrayRef(Position)));
|
||||
|
@ -449,7 +454,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
|
|||
|
||||
FullComment *Sema::actOnFullComment(
|
||||
ArrayRef<BlockContentComment *> Blocks) {
|
||||
return new (Allocator) FullComment(Blocks);
|
||||
return new (Allocator) FullComment(Blocks, ThisDeclInfo);
|
||||
}
|
||||
|
||||
void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
|
||||
|
@ -467,80 +472,30 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
|
|||
}
|
||||
|
||||
bool Sema::isFunctionDecl() {
|
||||
if (!IsThisDeclInspected)
|
||||
if (!ThisDeclInfo)
|
||||
return false;
|
||||
if (!ThisDeclInfo->IsFilled)
|
||||
inspectThisDecl();
|
||||
return IsFunctionDecl;
|
||||
return ThisDeclInfo->IsFunctionDecl;
|
||||
}
|
||||
|
||||
bool Sema::isTemplateDecl() {
|
||||
if (!IsThisDeclInspected)
|
||||
if (!ThisDeclInfo)
|
||||
return false;
|
||||
if (!ThisDeclInfo->IsFilled)
|
||||
inspectThisDecl();
|
||||
return IsTemplateDecl;
|
||||
return ThisDeclInfo->IsTemplateDecl;
|
||||
}
|
||||
|
||||
ArrayRef<const ParmVarDecl *> Sema::getParamVars() {
|
||||
if (!IsThisDeclInspected)
|
||||
if (!ThisDeclInfo->IsFilled)
|
||||
inspectThisDecl();
|
||||
return ParamVars;
|
||||
return ThisDeclInfo->ParamVars;
|
||||
}
|
||||
|
||||
void Sema::inspectThisDecl() {
|
||||
assert(!IsThisDeclInspected);
|
||||
if (!ThisDecl) {
|
||||
IsFunctionDecl = false;
|
||||
IsTemplateDecl = false;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>();
|
||||
TemplateParameters = NULL;
|
||||
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = true;
|
||||
IsTemplateDecl = false;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
|
||||
FD->getNumParams());
|
||||
TemplateParameters = NULL;
|
||||
unsigned NumLists = FD->getNumTemplateParameterLists();
|
||||
if (NumLists != 0) {
|
||||
IsTemplateDecl = true;
|
||||
TemplateParameters = FD->getTemplateParameterList(NumLists - 1);
|
||||
}
|
||||
} else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = true;
|
||||
IsTemplateDecl = false;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
|
||||
MD->param_size());
|
||||
TemplateParameters = NULL;
|
||||
} else if (const FunctionTemplateDecl *FTD =
|
||||
dyn_cast<FunctionTemplateDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = true;
|
||||
IsTemplateDecl = true;
|
||||
const FunctionDecl *FD = FTD->getTemplatedDecl();
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
|
||||
FD->getNumParams());
|
||||
TemplateParameters = FTD->getTemplateParameters();
|
||||
} else if (const ClassTemplateDecl *CTD =
|
||||
dyn_cast<ClassTemplateDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = false;
|
||||
IsTemplateDecl = true;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>();
|
||||
TemplateParameters = CTD->getTemplateParameters();
|
||||
} else if (const ClassTemplatePartialSpecializationDecl *CTPSD =
|
||||
dyn_cast<ClassTemplatePartialSpecializationDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = false;
|
||||
IsTemplateDecl = true;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>();
|
||||
TemplateParameters = CTPSD->getTemplateParameters();
|
||||
} else if (isa<ClassTemplateSpecializationDecl>(ThisDecl)) {
|
||||
IsFunctionDecl = false;
|
||||
IsTemplateDecl = true;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>();
|
||||
TemplateParameters = NULL;
|
||||
} else {
|
||||
IsFunctionDecl = false;
|
||||
IsTemplateDecl = false;
|
||||
ParamVars = ArrayRef<const ParmVarDecl *>();
|
||||
TemplateParameters = NULL;
|
||||
}
|
||||
ParamVarDocs.resize(ParamVars.size(), NULL);
|
||||
IsThisDeclInspected = true;
|
||||
ThisDeclInfo->fill();
|
||||
ParamVarDocs.resize(ThisDeclInfo->ParamVars.size(), NULL);
|
||||
}
|
||||
|
||||
unsigned Sema::resolveParmVarReference(StringRef Name,
|
||||
|
|
Загрузка…
Ссылка в новой задаче